Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Задачи

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про JavaScript: React, re-render, useMemo, useCallback, React.memo, performance optimization

Почему таймер, вынесенный в родительский компонент, вызывает ре-рендер дочерних компонентов и как это исправить?

Вопрос проверяет понимание механизма ре-рендеров в React при передаче пропсов, создаваемых в родительском компоненте, и умение оптимизировать производительность с помощью useMemo, useCallback или React.memo.

Короткий ответ

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

Длинный ответ

Почему таймер вызывает ре-рендер дочерних компонентов

В React каждый раз, когда обновляется состояние компонента (например, через setInterval), происходит его ре-рендер. При ре-рендере родителя все дочерние компоненты также перерисовываются по умолчанию, даже если их пропсы не изменились. Это связано с тем, что React не сравнивает пропсы автоматически — он просто вызывает render для всех потомков.

Проблема усугубляется, если в пропсы передаются функции или объекты, создаваемые прямо в JSX. При каждом рендере создаются новые ссылки, что ломает даже React.memo, если не использовать useCallback или useMemo.

Как это исправить

Есть три основных подхода:

  • React.memo — оборачивает компонент, чтобы он перерисовывался только при изменении пропсов (поверхностное сравнение).
  • useCallback — мемоизирует функцию, чтобы её ссылка оставалась стабильной между рендерами.
  • useMemo — мемоизирует результат вычисления или объект.

Пример кода

import React, { useState, useEffect, useCallback, memo } from 'react';

const Child = memo(({ onClick }) => {
  console.log('Child re-render');
  return <button onClick={onClick}>Click</button>;
});

function Parent() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const timer = setInterval(() => setCount(c => c + 1), 1000);
    return () => clearInterval(timer);
  }, []);

  // Без useCallback — новая функция каждый рендер
  const handleClick = useCallback(() => {
    console.log('Clicked');
  }, []);

  return (
    <div>
      <p>Count: {count}</p>
      <Child onClick={handleClick} />
    </div>
  );
}

В этом примере Child обёрнут в React.memo, а handleClick стабилизирован через useCallback. Благодаря этому Child не будет перерисовываться при каждом тике таймера.

Вывод

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

Frontend developer

tech
tech
tech
tech
tech
tech
tech
tech
tech

Ментор по Frontend

Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства

Записаться на консультацию

Уровень

  • Рейтинг:

    4

  • Сложность:

    5

Навыки

  • JavaScript

    JavaScript

  • React

    React

Ключевые слова

#React

#re-render

#useMemo

#useCallback

#React.memo

#performance optimization

Подпишись на React Developer в телеграм

Frontend developer

tech
tech
tech
tech
tech
tech
tech
tech
tech

Ментор по Frontend

Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства

Записаться на консультацию