updateState как основного механизма обновления в useStateВернемся к разбору принципов работы
useState. Следующим шагом рассмотрим updateState. Каждый раз, когда компонент обновляет свое состояние через useState, React вызывает функцию updateState.Исходный код
updateStateЗаглянем в исходный код:
function updateState<S>(
initialState: (() => S) | S,
): [S, Dispatch<BasicStateAction<S>>] {
return updateReducer(
basicStateReducer,
initialState
);
}
Сама функция выглядит просто и является обёрткой над
updateReducer. В неё мы передаем "базовый" reducer и исходные данные. В результате возвращается кортеж из текущего состояния и функции dispatch, она же setState.basicStateReducer: поддержка двух вариантов обновленияГлавный "секрет" работы
setState скрывается в basicStateReducer, который позволяет устанавливать новое состояние как для простых значений, так и для функции.function basicStateReducer<S>(state: S, action: BasicStateAction<S>): S {
return
typeof action === 'function'
? action(state)
: action;
}
Таким образом, мы можем писать два варианта кода:
const [count, setCount] =
useState(0);
setCount(5);
setCount(prev => prev + 1);
При этом, если передать функцию, то она вызывается с текущим состоянием внутри
action(state).Функция
updateReducerВернемся к основной функции
updateReducer:function updateReducer<S, I, A>(
reducer: (S, A) => S,
initialArg: I,
init?: (I) => S,
): [S, Dispatch<A>] {
const hook =
updateWorkInProgressHook();
return updateReducerImpl(
hook,
currentHook,
reducer
);
}
Обратим внимание, что она служит точкой входа как для
useState, так и для useReducer (к которому мы вернёмся позже, надеюсь скоро). Такое объединение позволяет обрабатывать очереди обновлений через единый слой API.Итак,
updateReducer принимает функцию reducer, начальные аргументы (передаются для совместимости интерфейса) и необязательную функцию инициализации; однако при вызове из updateState последний параметр не используется.Функция выполняет два ключевых действия:
Создаёт копию «рабочего/чернового» хука (
work‑in‑progress), позволяя React мутировать данные в фазе рендера, не затрагивая уже зафиксированные (мемоизированные) значения.Передаёт данные на обработку в функцию
updateReducerImpl, которая получает рабочий хук, текущий хук и reducer. Реализация updateReducerImpl вычисляет приоритет «полос движения» (lanes) и решает, можно ли отложить обновление компонента.А дальше?
Но перед тем как изучать ключевые функции современной архитектуры
React, предлагаю сделать небольшой шаг вглубь архитектурных паттернов React.---
#React #Fiber #useState #updateState #Hooks #ConcurrentMode #8bitJS