Как изменение states в одном месте в React влияло на рендеринг?
Рендеринг и производительность
Место хранения состояния определяет объём перерисовок. Работает правило каскада: обновление state рендерит компонент-владелец и всё его поддерево.
Эффект «состояние наверху»
const App = () => {
const [query, setQuery] = useState(''); // состояние в корне
return (
<>
<Search value={query} onChange={setQuery} />
<Sidebar /> {/* перерисовывается на каждый символ */}
<HeavyReport /> {/* и этот тоже */}
</>
);
};Одно изменение в корне → рендер всей страницы. Симптом: ввод в поле подтормаживает, профайлер показывает вспышку по всему дереву.
Как это лечится
Спуск состояния вниз: перенести useState внутрь Search — соседи перестают рендериться вовсе. Самый дешёвый и надёжный приём.
children как проп: обёртка со state не перерисовывает переданных ей детей (их элементы созданы выше и стабильны).
React.memo на тяжёлых соседях + стабильные props (useCallback/useMemo) — прерывает каскад, но требует дисциплины.
Разделение контекстов и узкие селекторы стора — та же идея для «глобального» состояния: не будить тех, кому данные не нужны.
Главное
Рендер ≠ обновление DOM: после диффа React может ничего не менять. Проблема возникает, когда рендеры частые (каждый символ) и дорогие (большие поддеревья, тяжёлые вычисления). Диагностика — React DevTools Profiler с опцией «why did this render».
Коротко для собеседования
Изменение state рендерит владельца и всё его поддерево, поэтому состояние, поднятое слишком высоко, перерисовывает всю страницу на каждый ввод. Лечится спуском состояния к месту использования, children-как-пропом, точечным React.memo и разделением контекстов/селекторами. Проверяется профайлером.