You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: beta/src/pages/learn/you-might-not-need-an-effect.md
+4-2Lines changed: 4 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -232,9 +232,11 @@ function List({ items }) {
232
232
}
233
233
```
234
234
235
-
**This pattern can be hard to understand, but it’s better than updating state in an Effect.** In the above example, `setSelection` is called directly during a render. React will re-render the `List`*immediately* after it exits with a `return` statement. By that point, React hasn't rendered the `List` children or updated the DOM yet, so this lets the `List` children skip rendering the stale `selection` value.[Read more about using this pattern correctly.](/apis/usestate#storing-information-from-previous-renders)
235
+
[Storing information from previous renders](/apis/usestate#storing-information-from-previous-renders) like this can be hard to understand, but it’s better than updating the same state in an Effect. In the above example, `setSelection` is called directly during a render. React will re-render the `List`*immediately* after it exits with a `return` statement. By that point, React hasn't rendered the `List` children or updated the DOM yet, so this lets the `List` children skip rendering the stale `selection` value.
236
236
237
-
Before moving on, consider whether you can further simplify the requirements to calculate everything during rendering. For example, instead of storing (and resetting) the selected *item*, you can store the selected *item ID:*
237
+
When you update a component during rendering, React throws away the returned JSX and immediately retries rendering. To avoid very slow cascading retries, React only lets you update the *same* component's state during a render. If you update another component's state during a render, you'll see an error. A condition like `items !== prevItems` is necessary to avoid loops. You may adjust state like this, but any other side effects (like changing the DOM or setting a timeout) should remain in event handlers or Effects to [keep your components predictable](/learn/keeping-components-pure).
238
+
239
+
**Although this pattern is more efficient than an Effect, most components shouldn't need it either.** No matter how you do it, adjusting state based on props or other state makes your data flow more difficult to understand and debug. Always check whether you can [reset all state with a key](#resetting-all-state-when-a-prop-changes) or [calculate everything during rendering](#updating-state-based-on-props-or-state) instead. For example, instead of storing (and resetting) the selected *item*, you can store the selected *item ID:*
Copy file name to clipboardExpand all lines: content/docs/hooks-faq.md
+11-43Lines changed: 11 additions & 43 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,4 +1,4 @@
1
-
---
1
+
---
2
2
id: hooks-faq
3
3
title: "Хуки: ответы на вопросы"
4
4
permalink: docs/hooks-faq.html
@@ -333,54 +333,22 @@ function useWindowPosition() {
333
333
334
334
### Как получить предыдущие пропсы или состояние? {#how-to-get-the-previous-props-or-state}
335
335
336
-
Сейчас, вы можете сделать это вручную, [используя реф](#is-there-something-like-instance-variables):
336
+
There are two cases in which you might want to get previous props or state.
337
337
338
-
```js{6,8}
339
-
function Counter() {
340
-
const [count, setCount] = useState(0);
338
+
Sometimes, you need previous props to **clean up an effect.** For example, you might have an effect that subscribes to a socket based on the `userId` prop. If the `userId` prop changes, you want to unsubscribe from the _previous_`userId` and subscribe to the _next_ one. You don't need to do anything special for this to work:
341
339
342
-
const prevCountRef = useRef();
343
-
useEffect(() => {
344
-
prevCountRef.current = count;
345
-
});
346
-
const prevCount = prevCountRef.current;
347
-
348
-
return <h1>Сейчас: {count}, до этого: {prevCount}</h1>;
349
-
}
350
-
```
351
-
352
-
Это может показаться усложнённым, но вы можете вынести эту логику в отдельный хук:
353
-
354
-
```js{3,7}
355
-
function Counter() {
356
-
const [count, setCount] = useState(0);
357
-
const prevCount = usePrevious(count);
358
-
return <h1>Сейчас: {count}, до этого: {prevCount}</h1>;
Обратите внимание, как это будет работать для пропсов, состояния или любого другого вычисляемого значения.
371
-
372
-
```js{5}
373
-
function Counter() {
374
-
const [count, setCount] = useState(0);
375
-
376
-
const calculation = count + 100;
377
-
const prevCalculation = usePrevious(calculation);
378
-
// ...
379
-
```
347
+
In the above example, if `userId` changes from `3` to `4`, `ChatAPI.unsubscribeFromSocket(3)` will run first, and then `ChatAPI.subscribeToSocket(4)` will run. There is no need to get "previous" `userId` because the cleanup function will capture it in a closure.
380
348
381
-
Возможно, в будущем API React введёт хук `usePrevious`, так как он требуется довольно часто.
349
+
Other times, you might need to **adjust state based on a change in props or other state**. This is rarely needed and is usually a sign you have some duplicate or redundant state. However, in the rare case that you need this pattern, you can [store previous state or props in state and update them during rendering](#how-do-i-implement-getderivedstatefromprops).
382
350
383
-
Также смотрите [рекомендованный паттерн для производного состояния](#how-do-i-implement-getderivedstatefromprops).
351
+
We have previously suggested a custom Hook called `usePrevious` to hold the previous value. However, we've found that most use cases fall into the two patterns described above. If your use case is different, you can [hold a value in a ref](#is-there-something-like-instance-variables) and manually update it when needed. Avoid reading and updating refs during rendering because this makes your component's behavior difficult to predict and understand.
384
352
385
353
### Почему я вижу устаревшие пропсы или состояние в моей функции? {#why-am-i-seeing-stale-props-or-state-inside-my-function}
0 commit comments