Запрет обновления (memo) дочернего компонента в React - IZIART

Разработка сайтов
индивидуальный дизайн

Главная » React » Запрет обновления (memo) дочернего компонента в React

Запрет обновления (memo) дочернего компонента в React

Обновлено: 14.11.2024
react

Оптимизация Рендеринга в React с помощью React.memo и useCallback

Как можно использовать React.memo и useCallback для оптимизации рендеринга компонентов в React. Это полезные инструменты для предотвращения ненужных повторных рендеров дочерних компонентов, улучшения производительности и упрощения кода в ситуациях, когда функции передаются в качестве пропсов.

Основная идея примера

В компоненте App есть состояние count, которое отслеживается с помощью хука useState. Когда состояние count обновляется, родительский компонент App рендерится заново. Для управления обновлением состояния создается функция onIncrement, которая увеличивает значение count на 1.

Использование React.memo

const ChildComponent = memo(({ onIncrement }) => {
  console.log("Рендер дочернего компонента");
  return <button onClick={onIncrement}>Увеличить в дочернем компоненте</button>;
});

React.memo предотвращает повторный рендер ChildComponent, если его пропсы не изменяются. Однако, если функция onIncrement пересоздается на каждом рендере родительского компонента, React.memo будет считать, что пропсы изменились, что приведет к повторному рендеру ChildComponent.

К содержанию ↑

Проблема пересоздания функции

Каждый раз, когда App рендерится, создается новая версия функции onIncrement. Поскольку функция передается как пропс в ChildComponent, это приводит к его повторному рендеру, даже если count не изменился.

Решение с useCallback

Хук useCallback используется для мемоизации функции onIncrement:

const onIncrement = useCallback(() => {
  setCount((prevCount) => prevCount + 1);
}, []);

Теперь onIncrement будет пересоздаваться только при изменении зависимостей (в данном случае зависимостей нет, так как массив зависимостей пуст). Это позволяет React.memo правильно предотвратить повторный рендер ChildComponent.

Полный код

const ChildComponent = memo(({ onIncrement }: any) => {
  console.log("Рендер дочернего компонента");
  return <button onClick={onIncrement}>Увеличить в дочернем компоненте</button>;
});


const App: React.FC = () => {
  const [count, setCount] = useState(0);

  // Без useCallback каждый рендер ParentComponent будет пересоздавать onIncrement,
  // вызывая повторный рендер ChildComponent.
  const onIncrement = useCallback(() => {
    setCount((prevCount) => prevCount + 1);
  }, []);
  

  return (
    <div>
      <p>count: {count}</p>
      <ChildComponent onIncrement={onIncrement} />
    </div>
  );
};

Благодаря использованию React.memo и useCallback мы добились оптимизации рендеринга. Дочерний компонент ChildComponent рендерится только один раз при первом рендере родительского компонента и больше не рендерится повторно, пока не изменяются его пропсы. Это значительно улучшает производительность, особенно если в вашем приложении есть многоуровневые компоненты или сложные вычисления в дочерних компонентах.

Будет интересно