Как работают вместе useMemo, useCallback и React.memo? Почему важно оборачивать функции в useCallback при передаче в дочерний компонент, обёрнутый в React.memo?
Ответ от нейросети
sobes.tech AI
useMemo, useCallback и React.memo работают вместе для оптимизации производительности React-компонентов, предотвращая ненужные рендеры и пересоздание функций или значений.
- React.memo — это HOC, который мемоизирует компонент, предотвращая его повторный рендер, если пропсы не изменились по сравнению с предыдущим рендером.
- useCallback мемоизирует функцию, возвращая ту же функцию между рендерами, если зависимости не изменились.
- useMemo мемоизирует вычисленное значение, чтобы не пересчитывать его без необходимости.
Почему важно оборачивать функции в useCallback при передаче в дочерний компонент с React.memo:
Если родительский компонент передаёт функцию как пропс, то при каждом рендере эта функция создаётся заново (новый объект в памяти). Даже если остальные пропсы не изменились, React.memo увидит, что функция изменилась (сравнение по ссылке), и перерендерит дочерний компонент.
Оборачивая функцию в useCallback, мы гарантируем, что ссылка на функцию останется той же, пока зависимости не изменятся, и React.memo сможет эффективно предотвратить лишний рендер.
Пример:
const Child = React.memo(({ onClick }) => {
console.log('Child rendered');
return <button onClick={onClick}>Click me</button>;
});
function Parent() {
const [count, setCount] = React.useState(0);
// Без useCallback функция создаётся заново при каждом рендере
// const handleClick = () => setCount(c => c + 1);
// С useCallback функция мемоизируется
const handleClick = React.useCallback(() => setCount(c => c + 1), []);
return <Child onClick={handleClick} />;
}
Без useCallback Child будет ререндериться при каждом обновлении Parent, с useCallback — только при изменении зависимостей.