Хуки оптимизации и кэширования
useCallback, useMemo, React.Memo (HOC)
useCallback
useCallback — это хук в React, который используется для мемоизации функций. Он помогает оптимизировать производительность компонентов, особенно когда речь идет о передаче функций в дочерние компоненты или их использование в зависимостях других хуков, таких как useEffect.
Зачем нужен useCallback?
- Оптимизация рендеринга дочерних компонентов:
- В React компоненты перерисовываются, если изменяются их пропсы или состояние.
- Если вы передаете функцию как пропс в дочерний компонент, и эта функция создается заново при каждом рендере родительского компонента, то дочерний компонент будет перерисовываться даже если это не нужно.
useCallbackпозволяет сохранить ссылку на одну и ту же функцию между рендерами, если её зависимости не изменились. Это предотвращает ненужные перерисовки дочерних компонентов.
- Избежание лишних вызовов
useEffect:- Если функция используется в зависимостях
useEffect, то каждый раз, когда функция создается заново,useEffectбудет срабатывать снова. - useCallback позволяет избежать этого, сохраняя стабильную ссылку на функцию.
- Если функция используется в зависимостях
- Улучшение производительности:
- Создание функций в JavaScript — это операция, которая занимает время и память. Если функция не изменяется, то нет смысла создавать её заново при каждом рендере.
Как работает useCallback?
useCallback принимает два аргумента:
- Функция, которую нужно мемоизировать.
- Массив зависимостей.
Хук возвращает мемоизированную версию функции, которая изменяется только тогда, когда изменяются значения в массиве зависимостей.
Когда использовать useCallback?
- Когда функция передается в качестве пропса в дочерний компонент, который оптимизирован с помощью
React.memo. - Когда функция используется в зависимостях других хуков, таких как
useEffect. - Когда создание функции является дорогостоящей операцией.
Когда не нужно использовать useCallback?
- Если функция не передается в дочерние компоненты или не используется в зависимостях других хуков.
- Если функция простая и её создание не влияет на производительность.
Использование useCallback должно быть обоснованным, так как избыточное применение может усложнить код и не принести значительной пользы.
React.memo
React.memo — это функция высшего порядка (Higher-Order Component, HOC), которая используется для оптимизации производительности функциональных компонентов в React. Она позволяет избежать лишних рендеров компонента, если его пропсы не изменились.
Как работает React.memo?
Когда вы оборачиваете компонент в React.memo, React запоминает (мемоизирует) результат его рендеринга. При последующих рендерах React сравнивает текущие пропсы с предыдущими. Если пропсы не изменились, React использует закэшированный результат рендеринга, вместо того чтобы выполнять рендер компонента заново.
Кастомная функция сравнения:
По умолчанию React.memo поверхностно сравнивает пропсы (с использованием Object.is). Если вам нужно более сложное сравнение, вы можете передать вторым аргументом кастомную функцию сравнения:
const MyComponent = React.memo(
function MyComponent(props) {
// Логика компонента
},
(prevProps, nextProps) => {
// Возвращает true, если пропсы считаются равными (рендер не нужен)
// Возвращает false, если пропсы изменились (рендер нужен)
return prevProps.value === nextProps.value;
}
);
Когда использовать React.memo?
- Компоненты, которые часто рендерятся с одинаковыми пропсами:
- Если компонент часто рендерится, но его пропсы редко меняются, React.memo поможет избежать лишних рендеров.
- Тяжелые компоненты:
- Если компонент выполняет сложные вычисления или рендерит большое количество элементов,
React.memoможет значительно улучшить производительность.
- Если компонент выполняет сложные вычисления или рендерит большое количество элементов,
- Компоненты, которые получают стабильные пропсы:
- Если пропсы компонента редко меняются (например, данные из контекста или мемоизированные значения),
React.memoбудет полезен.
- Если пропсы компонента редко меняются (например, данные из контекста или мемоизированные значения),
Когда не нужно использовать React.memo?
- Легковесные компоненты:
- Если компонент простой и его рендер не требует значительных ресурсов, использование
React.memoможет быть избыточным.
- Если компонент простой и его рендер не требует значительных ресурсов, использование
- Компоненты, пропсы которых часто меняются:
- Если пропсы компонента часто меняются,
React.memoне принесет пользы, так как компонент всё равно будет перерисовываться.
- Если пропсы компонента часто меняются,
- Компоненты с побочными эффектами:
- Если компонент зависит от побочных эффектов (например, от глобального состояния),
React.memoможет не сработать как ожидается.
- Если компонент зависит от побочных эффектов (например, от глобального состояния),
Важные моменты:
React.memoработает только с функциональными компонентами.- Он не предотвращает рендеры, вызванные изменением состояния внутри компонента.
- Используйте
React.memoтолько там, где это действительно необходимо, чтобы не усложнять код без нужды.
useMemo
Хук useMemo в React используется для мемоизации (запоминания) значений. Он позволяет оптимизировать производительность, избегая повторных вычислений значений, которые не изменились между рендерами. Это особенно полезно для дорогостоящих вычислений или операций, которые зависят от определенных данных.
Как работает useMemo?
useMemo принимает два аргумента:
- Функция, которая возвращает значение (эта функция будет выполнена только при изменении зависимостей).
- Массив зависимостей — список значений, при изменении которых функция будет выполнена заново.
Хук возвращает мемоизированное значение, которое будет пересчитано только при изменении зависимостей.
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
Когда использовать useMemo?
- Дорогостоящие вычисления:
- Если у вас есть сложные вычисления, которые занимают много времени (например, сортировка больших массивов, математические операции и т.д.),
useMemoпоможет избежать их повторного выполнения.
- Если у вас есть сложные вычисления, которые занимают много времени (например, сортировка больших массивов, математические операции и т.д.),
- Оптимизация рендеров:
- Если значение используется в рендере компонента и зависит от пропсов или состояния,
useMemoпредотвратит лишние рендеры, если зависимости не изменились.
- Если значение используется в рендере компонента и зависит от пропсов или состояния,
- Передача мемоизированных значений в дочерние компоненты:
- Если вы передаете вычисленное значение как пропс в дочерний компонент,
useMemoпоможет избежать лишних рендеров дочернего компонента.
- Если вы передаете вычисленное значение как пропс в дочерний компонент,
Когда не нужно использовать useMemo?
- Легковесные вычисления:
- Если вычисления простые и не требуют значительных ресурсов, использование
useMemoможет быть избыточным.
- Если вычисления простые и не требуют значительных ресурсов, использование
- Часто изменяющиеся зависимости:
- Если зависимости часто меняются,
useMemoне принесет пользы, так как значение будет пересчитываться при каждом рендере.
- Если зависимости часто меняются,
- Не связанные с рендером значения:
- Если значение не используется в рендере или не влияет на производительность,
useMemoне нужен.
- Если значение не используется в рендере или не влияет на производительность,
Важные моменты:
useMemoне гарантирует, что функция не будет выполнена. Она может быть вызвана React для "подстраховки" (например, при изменении приоритетов рендеринга).- Используйте
useMemoтолько там, где это действительно необходимо, чтобы не усложнять код без нужды.
🚀 Источник: DeepSeek
🚀 Источник: YT: memo vs useMemo vs useCallback в React. В чём разница?