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).
#### Как useCallback связан с useMemo? {/*how-is-usecallback-related-to-usememo*/}
169
169
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) (или, другими словами, кешировать) что-то, что вы передаете вниз по иерархии:
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';
@@ -202,7 +202,7 @@ function ProductPage({ productId, referrer }) {
202
202
Если вы уже знакомы с [`useMemo`,](/reference/react/useMemo) вам может быть полезно думать о `useCallback` так:
203
203
204
204
```js
205
-
//Simplified implementation (inside React)
205
+
//Упрощённая реализация (внутри React)
206
206
functionuseCallback(fn, dependencies) {
207
207
returnuseMemo(() => fn, dependencies);
208
208
}
@@ -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` в других случаях. Это не принесёт значительного вреда, поэтому некоторые команды решают не думать о конкретных случаях и мемоизируют как можно больше. Недостатком является то, что код становится менее читаемым. Кроме того, не всякая мемоизация эффективна: одно значение, которое «всегда новое», достаточно, чтобы сломать мемоизацию для всего компонента.
@@ -235,17 +235,17 @@ function useCallback(fn, dependencies) {
235
235
1. Избегайте [ненужных эффектов, которые обновляют состояние.](/learn/you-might-not-need-an-effect) Большинство проблем с производительностью в приложениях React вызвано цепочками обновлений, исходящими от эффектов, которые заставляют ваши компоненты рендериться снова и снова.
236
236
1. Попытайтесь [удалить ненужные зависимости из ваших эффектов.](/learn/removing-effect-dependencies) Например, вместо мемоизации часто проще переместить какой-то объект или функцию внутрь эффекта или за пределы компонента.
237
237
238
-
Если конкретное взаимодействие все еще кажется медленным, [используйте профайлер в React Developer Tools,](https://legacy.reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html) чтобы определить, какие компоненты больше всего выиграют от мемоизации, и добавьте мемоизацию там, где это необходимо. Эти принципы делают ваши компоненты легче для отладки и понимания, поэтому хорошо следовать им в любом случае. В долгосрочной перспективе мы исследуем [возможность автоматической мемоизации](https://www.youtube.com/watch?v=lGEMwh32soc), чтобы решить эту проблему раз и навсегда.
238
+
Если конкретное взаимодействие все ещё кажется медленным, [используйте профайлер в React Developer Tools,](https://legacy.reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html) чтобы определить, какие компоненты больше всего выиграют от мемоизации, и добавьте мемоизацию там, где это необходимо. Эти принципы делают ваши компоненты легче для отладки и понимания, поэтому хорошо следовать им в любом случае. В долгосрочной перспективе мы исследуем [возможность автоматической мемоизации](https://www.youtube.com/watch?v=lGEMwh32soc), чтобы решить эту проблему раз и навсегда.
239
239
240
240
</DeepDive>
241
241
242
242
<Recipes titleText="Разница между useCallback и непосредственным объявлением функции" titleId="examples-rerendering">
243
243
244
244
#### Пропуск повторного рендеринга с помощью `useCallback` и `memo` {/*skipping-re-rendering-with-usecallback-and-memo*/}
245
245
246
-
В этом примере компонент `ShippingForm` **искусственно замедлен,** чтобы вы могли увидеть, что происходит, когда React-компонент действительно медленный. Попробуйте увеличить счетчик и переключить тему.
246
+
В этом примере компонент `ShippingForm` **искусственно замедлен,** чтобы вы могли увидеть, что происходит, когда React-компонент действительно медленный. Попробуйте увеличить счётчик и переключить тему.
247
247
248
-
Увеличение счетчика ощущается медленным, потому что это вынуждает замедленный `ShippingForm` повторно рендериться. Это ожидаемо, так как счетчик изменился, и нужно отобразить новый выбор пользователя на экране.
248
+
Увеличение счётчика ощущается медленным, потому что это вынуждает замедленный `ShippingForm` повторно рендериться. Это ожидаемо, так как счётчик изменился, и нужно отобразить новый выбор пользователя на экране.
249
249
250
250
Теперь попробуйте переключить тему. **Благодаря `useCallback` вместе с [`memo`](/reference/react/memo), это происходит быстро, несмотря на искусственное замедление!** `ShippingForm` пропустил повторный рендер, потому что функция `handleSubmit` не изменилась. Функция `handleSubmit` не изменилась, потому что `productId` и `referrer` (зависимости вашего `useCallback`) не изменились с момента последнего рендера.
251
251
@@ -716,7 +716,7 @@ function ChatRoom({ roomId }) {
716
716
// ...
717
717
```
718
718
719
-
Это создает проблему. [Каждое реактивное значение должно быть объявлено как зависимость вашего эффекта.](/learn/lifecycle-of-reactive-effects#react-verifies-that-you-specified-every-reactive-value-as-a-dependency) Однако, если вы объявите `createOptions` как зависимость, это приведет к постоянному повторному подключению эффекта к чат-комнате:
719
+
Это создаёт проблему. [Каждое реактивное значение должно быть объявлено как зависимость вашего эффекта.](/learn/lifecycle-of-reactive-effects#react-verifies-that-you-specified-every-reactive-value-as-a-dependency) Однако, если вы объявите `createOptions` как зависимость, это приведёт к постоянному повторному подключению эффекта к чат-комнате:
720
720
721
721
722
722
```js {6}
@@ -847,7 +847,7 @@ function ProductPage({ productId, referrer }) {
847
847
```
848
848
849
849
850
-
Вы можете щелкнуть правой кнопкой мыши на массивах из разных рендеров в консоли и выбрать "Store as global variable" для обоих. Предположим, первый сохранен как `temp1` , а второй как `temp2`. Затем вы можете использовать консоль браузера, чтобы проверить, являются ли каждая зависимость в обоих массивах одинаковыми:
850
+
Вы можете щёлкнуть правой кнопкой мыши на массивах из разных рендеров в консоли и выбрать "Store as global variable" для обоих. Предположим, первый сохранён как `temp1` , а второй как `temp2`. Затем вы можете использовать консоль браузера, чтобы проверить, являются ли каждая зависимость в обоих массивах одинаковыми:
851
851
852
852
```js
853
853
Object.is(temp1[0], temp2[0]); // Первая зависимость одинаковая в обоих массивах?
@@ -861,7 +861,7 @@ Object.is(temp1[2], temp2[2]); // ... и так далее для каждой
861
861
862
862
### Мне нужно вызвать `useCallback` для каждого элемента списка в цикле, но это не разрешено {/*i-need-to-call-usememo-for-each-list-item-in-a-loop-but-its-not-allowed*/}
863
863
864
-
Предположим, что компонент `Chart`обернут в [`memo`](/reference/react/memo). Вы хотите пропустить повторный рендеринг каждого `Chart` в списке, когда компонент `ReportList` рендерится заново. Однако вы не можете вызывать `useCallback` в цикле:
864
+
Предположим, что компонент `Chart`обёрнут в [`memo`](/reference/react/memo). Вы хотите пропустить повторный рендеринг каждого `Chart` в списке, когда компонент `ReportList` рендерится заново. Однако вы не можете вызывать `useCallback` в цикле:
0 commit comments