> Увидим ли мы изменения в дочернем компоненте через пропсы, если переменная изменилась, но ререндер не произошел? (React)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: DigitalSail

Стек: React

> Пример ответа

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

Нет, изменений в дочернем компоненте через пропсы не будет, если ререндер родителя не произошёл. React обновляет пропсы дочернего компонента только при ререндере родителя. Даже если переменная изменилась в замыкании или через мутацию объекта, React не узнает об этом без вызова setState или forceUpdate.

Подробное объяснение

React использует декларативный подход: UI - это функция от состояния. Пропсы передаются вниз по дереву компонентов во время рендера. Если родительский компонент не ререндерится (не вызван setState, не изменены пропсы от вышестоящего компонента, не вызван forceUpdate), то дочерний компонент не получит новые пропсы, даже если переменная, используемая для вычисления пропсов, изменилась.

Это связано с тем, что React работает на основе реактивного обновления через setState, а не через отслеживание изменений переменных (как в Vue или MobX). Изменение обычной переменной (let, const, объект, массив) не триггерит ререндер. React не имеет механизма "подписки" на произвольные переменные.

Исключение: если дочерний компонент обёрнут в React.memo, он всё равно получит новые пропсы при ререндере родителя, но может пропустить свой собственный ререндер, если пропсы поверхностно равны. Однако без ререндера родителя пропсы не обновятся.

На практике

Эта проблема часто возникает при:

  • Использовании мутаций объектов/массивов вместо создания новых ссылок
  • Хранении данных вне React-состояния (в замыканиях, глобальных переменных, ref)
  • Попытке передать изменённое значение через пропсы без вызова setState

Решение: всегда использовать setState для данных, которые должны вызывать ререндер. Если нужно передать изменяемое значение без ререндера всего дерева - используйте useRef и callback'и, но не пропсы.

Пример кода

JSX
// Проблема: ререндер не произойдёт
function Parent() {
let count = 0; // обычная переменная, не state
const handleClick = () => {
count++; // меняем, но ререндера нет
};
return <Child value={count} />; // Child не увидит изменения
}
// Решение: используем useState
function Parent() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(prev => prev + 1); // триггерит ререндер
};
return <Child value={count} />; // Child получит новый пропс
}

Как отвечать на собеседовании

Начни с чёткого "нет", затем объясни механизм: ререндер родителя - необходимое условие для обновления пропсов. Упомяни, что React не отслеживает изменения переменных, только вызовы setState. Добавь про React.memo - он не решает проблему, а только оптимизирует уже произошедший ререндер. Приведи пример с мутацией объекта. Закончи практическим советом: всегда использовать setState для данных, влияющих на UI.

Что проверяет интервьюер

  • Понимание жизненного цикла React и механизма ререндера
  • Различие между обычными переменными и состоянием
  • Знание, что пропсы - это снимок состояния на момент рендера
  • Умение диагностировать проблемы с обновлением UI
  • Понимание ограничений React.memo

Типичные ошибки

  • Утверждение, что изменение пропсов само по себе вызывает ререндер
  • Путаница между изменением ссылки на объект и мутацией объекта
  • Мысль, что React.memo или useMemo решают проблему отсутствия ререндера
  • Ожидание, что изменение ref.current вызовет обновление пропсов
  • Использование forceUpdate как основного решения вместо правильного управления состоянием

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью