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
+20-3Lines changed: 20 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -333,12 +333,15 @@ function useWindowPosition() {
333
333
334
334
### Как получить предыдущие пропсы или состояние? {#how-to-get-the-previous-props-or-state}
335
335
336
+
<<<<<<< HEAD
336
337
Сейчас, вы можете сделать это вручную, [используя реф](#is-there-something-like-instance-variables):
338
+
=======
339
+
There are two cases in which you might want to get previous props or state.
340
+
>>>>>>> ee7705675d2304c53c174b9fb316e2fbde1e9fb3
337
341
338
-
```js{6,8}
339
-
function Counter() {
340
-
const [count, setCount] = useState(0);
342
+
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
343
344
+
<<<<<<< HEAD
342
345
const prevCountRef = useRef();
343
346
useEffect(() => {
344
347
prevCountRef.current = count;
@@ -381,6 +384,20 @@ function Counter() {
381
384
Возможно, в будущем API React введёт хук `usePrevious`, так как он требуется довольно часто.
382
385
383
386
Также смотрите [рекомендованный паттерн для производного состояния](#how-do-i-implement-getderivedstatefromprops).
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.
396
+
397
+
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).
398
+
399
+
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.
400
+
>>>>>>> ee7705675d2304c53c174b9fb316e2fbde1e9fb3
384
401
385
402
### Почему я вижу устаревшие пропсы или состояние в моей функции? {#why-am-i-seeing-stale-props-or-state-inside-my-function}
0 commit comments