PassFront
  1. PassFront
  2. База знаний
  3. Компоненты

Будут ли перерисовываться дочерние компоненты, если у родительского изменилось состояние?

Компоненты

Да — по умолчанию при изменении состояния родителя перерисовываются все его дочерние компоненты, независимо от того, изменились их props или нет.

Как это работает

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

  return (
    <>
      <button onClick={() => setCount(count + 1)}>{count}</button>
      <Child />               {/* нет props — всё равно перерисуется */}
      <Static text="hello" /> {/* props не менялись — всё равно перерисуется */}
    </>
  );
};

Рендер каскадный: React вызывает функцию родителя, а затем рекурсивно всех детей, внуков и т.д. Проверки «изменились ли props» по умолчанию нет — она стоила бы дороже на каждом узле, чем повторный вызов лёгких функций.

Перерисовка (вызов функции) не означает изменения DOM: после диффа React внесёт правки только там, где вывод реально отличается. Поэтому чаще всего каскад безвреден.

Исключения — когда дети НЕ перерисуются

React.memo — при поверхностно равных props:

const Child = React.memo(ChildInner);

Стабильные элементы (children-как-проп) — если JSX ребёнка создан вне обновившегося компонента, React видит тот же элемент и пропускает его:

const Wrapper = ({ children }) => {
  const [n, setN] = useState(0);
  return <div onClick={() => setN(n + 1)}>{children}</div>;
  // children созданы родителем Wrapper — при изменении n НЕ перерисуются
};

Коротко для собеседования

Да, каскадом вниз и без проверки props — так React устроен по умолчанию; но рендер ≠ изменение DOM (дифф внесёт минимум). Прервать каскад можно React.memo или паттерном children-как-проп (стабильные элементы, созданные выше, пропускаются).

Другие вопросы раздела