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
* `fn`: Значение функции, которую вы хотите кешировать, может принимать любые аргументы и возвращать любые значения. React вернет (но не вызовет!) вашу функцию при первом рендере. При последующих рендерах React даст вам ту же функцию, если `dependencies` не изменились. В противном случае он вернет функцию, переданную при текущем рендере, и сохранит её для возможного повторного использования. React не вызывает вашу функцию, он возвращает её вам, чтобы вы могли решить, когда и нужно ли её вызывать.
41
+
* `fn`: Значение функции, которую вы хотите кешировать. Она может принимать любые аргументы и возвращать любые значения. React вернет (но не вызовет!) вашу функцию при первом рендере. При последующих рендерах React даст вам ту же функцию, если `dependencies` не изменились. В противном случае он вернет функцию, переданную при текущем рендере, и сохранит её для возможного повторного использования. React не вызывает вашу функцию. Он возвращает её вам, чтобы вы могли решить, когда и нужно ли её вызывать.
42
42
43
43
* `dependencies`: Список всех реактивных значений, на которые ссылается код `fn`. К реактивным значениям относятся пропсы, состояние и все переменные и функции, объявленные непосредственно в теле компонента. Если ваш линтер [настроен для использования с React](/learn/editor-setup#linting), он проверит, что каждое реактивное значение правильно указано как зависимость. Список зависимостей должен иметь постоянное количество элементов и быть записан примерно так: `[dep1, dep2, dep3]`. React будет сравнивать каждую зависимость с её предыдущим значением, используя алгоритм сравнения [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is).
1. Функцию, которую вы хотите кешировать между рендерами.
81
+
1. Функцию, которую вы хотите кешировать между повторными рендерами.
82
82
2. <CodeStep step={2}>Список зависимостей</CodeStep>, включающий каждое значение внутри вашего компонента, которое используется внутри функции.
83
83
84
84
При первом рендере <CodeStep step={3}>возвращаемая функция</CodeStep> из `useCallback` будет той функцией, которую вы передали.
85
85
86
86
При последующих рендерах React сравнит <CodeStep step={2}>зависимости</CodeStep> с теми, которые вы передали при предыдущем рендере. Если ни одна из зависимостей не изменилась (сравнение производится с помощью [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is)), `useCallback` вернёт ту же функцию, что и раньше. В противном случае, `useCallback` вернёт функцию, переданную при *текущем* рендере.
87
87
88
-
Другими словами, `useCallback` кеширует функцию между рендерами до тех пор, пока её зависимости не изменятся.
88
+
Другими словами, `useCallback` кеширует функцию между повторными рендерами до тех пор, пока её зависимости не изменятся.
89
89
90
90
**Давайте рассмотрим пример, чтобы понять, когда это полезно.**
Вы заметили, что при переключении пропса `theme` приложение на мгновение зависает, но если убрать `<ShippingForm />` из вашего JSX, оно работает быстро. Это говорит о том, что стоит попытаться оптимизировать компонент `ShippingForm`.
105
105
106
-
**По умолчанию, когда компонент повторно рендерится, React рекурсивно рендерит всех его дочерних компонентов.** Поэтому, когда `ProductPage` рендерится с другой `theme`, компонент `ShippingForm` *тоже* повторно рендерится. Это нормально для компонентов, которые не требуют больших вычислений при рендере. Но если повторный рендер медленный, можно сказать `ShippingForm` пропустить рендеринг, если его пропсы такие же, как при последнем рендере, обернув его в [`memo`:](/reference/react/memo)
106
+
**По умолчанию, когда компонент повторно рендерится, React рекурсивно отрендерит снова все его дочерние компоненты.** Поэтому, когда `ProductPage` рендерится с другой `theme`, компонент `ShippingForm` *тоже* повторно рендерится. Это нормально для компонентов, которые не требуют больших вычислений при рендере. Но если повторный рендер медленный, можно сказать `ShippingForm` пропустить повторный рендеринг, если его пропсы такие же, как при последнем рендере, обернув его в [`memo`:](/reference/react/memo)
**Оборачивая `handleSubmit` в `useCallback`, вы гарантируете, что это *одна и та же* функция между рендерами** (пока зависимости не изменятся). Вам *не нужно* оборачивать функцию в `useCallback`, если на это нет конкретной причины. В этом примере причина в том, что вы передаёте её в компонент, обёрнутый в [`memo`,](/reference/react/memo), что позволяет ему пропускать повторные рендеры. Есть и другие причины использовать `useCallback`, которые описаны далее на этой странице.
158
+
**Оборачивая `handleSubmit` в `useCallback`, вы гарантируете, что это *одна и та же* функция между повторными рендерами** (пока зависимости не изменятся). Вам *не нужно* оборачивать функцию в `useCallback`, если на это нет конкретной причины. В этом примере причина в том, что вы передаёте её в компонент, обёрнутый в [`memo`,](/reference/react/memo) что позволяет ему пропускать повторные рендеры. Есть и другие причины использовать `useCallback`, которые описаны далее на этой странице.
#### Как useCallback связан с useMemo? {/*how-is-usecallback-related-to-usememo*/}
169
169
170
-
Вы часто увидите [`useMemo`](/reference/react/useMemo) вместе с `useCallback`. . Оба они полезны при оптимизации дочернего компонента. Они позволяют вам [мемоизировать](https://en.wikipedia.org/wiki/Memoization) (или, другими словами, кешировать) что-то, что вы передаете вниз по иерархии:
170
+
Вы часто увидите [`useMemo`](/reference/react/useMemo) вместе с `useCallback`. Они оба полезны при оптимизации дочернего компонента. Они позволяют вам [мемоизировать](https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D0%BC%D0%BE%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) (или, другими словами, кешировать) что-то, что вы передаете вниз по иерархии:
171
171
172
172
```js {6-8,10-15,19}
173
173
import { useMemo, useCallback } from'react';
@@ -220,7 +220,7 @@ function useCallback(fn, dependencies) {
220
220
221
221
Кеширование функции с помощью `useCallback` полезно в нескольких случаях:
222
222
223
-
- Вы передаете её как пропс компоненту, обёрнутому в [`memo`.](/reference/react/memo). Вы хотите пропустить повторный рендер, если значение не изменилось. Меморизация позволяет вашему компоненту повторно рендериться только если зависимости изменились.
223
+
- Вы передаете её как пропс компоненту, обёрнутому в [`memo`.](/reference/react/memo) Вы хотите пропустить повторный рендер, если значение не изменилось. Меморизация позволяет вашему компоненту повторно рендериться только если зависимости изменились.
224
224
- Функция, которую вы передаёте, позже используется как зависимость в каком-то хуке. Например, другая функция, обёрнутая в `useCallback`, зависит от неё, или вы зависите от этой функции в [`useEffect.`](/reference/react/useEffect)
225
225
226
226
Нет смысла оборачивать функцию в `useCallback` в других случаях. Это не принесёт значительного вреда, поэтому некоторые команды решают не думать о конкретных случаях и мемоизируют как можно больше. Недостатком является то, что код становится менее читаемым. Кроме того, не всякая мемоизация эффективна: одно значение, которое «всегда новое», достаточно, чтобы сломать мемоизацию для всего компонента.
@@ -265,7 +265,7 @@ export default function App() {
265
265
checked={isDark}
266
266
onChange={e=>setIsDark(e.target.checked)}
267
267
/>
268
-
Dark mode
268
+
Тёмный режим
269
269
</label>
270
270
<hr />
271
271
<ProductPage
@@ -405,7 +405,7 @@ export default function App() {
405
405
checked={isDark}
406
406
onChange={e=>setIsDark(e.target.checked)}
407
407
/>
408
-
Dark mode
408
+
Тёмный режим
409
409
</label>
410
410
<hr />
411
411
<ProductPage
@@ -539,7 +539,7 @@ export default function App() {
0 commit comments