Изменится ли React функциональный компонент при вызове сеттера useState
Что проверяют
Понимаете ли вы модель рендера React: что происходит после вызова сеттера и почему переменная состояния в текущем вызове не меняется. Следом почти всегда показывают три setCount(count + 1) подряд и просят назвать результат.
Как отвечать
Сеттер не меняет переменную, он ставит обновление в очередь и планирует повторный рендер. React снова вызовет функцию компонента, useState вернёт новое значение, и после сравнения деревьев в DOM попадут только реальные отличия. Переменная count внутри текущего вызова это снимок: она постоянна для всего рендера и всех созданных в нём замыканий.
Что стоит проговорить:
- пакетирование: с React 18 обновления объединяются везде, в том числе в промисах и
setTimeout. Несколько сеттеров подряд дают один рендер; - функциональная форма:
setCount(count + 1)трижды даст плюс один, все три видят один снимок.setCount(c => c + 1)трижды даст плюс три; - пропуск рендера: если новое значение равно текущему по
Object.is, React пропускает обновление. Мутация массива с передачей той же ссылки ничего не перерисует, нужна новая:setItems([...items, x]); - дети: рендер компонента по умолчанию запускает рендер всех дочерних. Отсечь его можно
React.memoили вынесением состояния ниже, а включённый React Compiler расставляет мемоизацию сам.
Состояние хранится не в функции, а в fiber-узле, привязанном к позиции компонента в дереве. Поэтому оно переживает повторные вызовы и теряется при размонтировании или смене типа элемента на этом месте.
Где спотыкаются
Ждут новое значение в console.log сразу после сеттера или отправляют старое в запрос строкой ниже. Правильно вычислить новое значение в переменную и использовать её.
Говорят, что компонент рендерится только при изменении своего состояния. Он рендерится и вслед за родителем, и при смене значения контекста.
Вызывают сеттер прямо в теле компонента без условия и получают ошибку «Too many re-renders».