Если вы проверите реализацию на React github, вы заметите, что useState
просто вызывает useReducer
с базовым редуктором:
export function useState<S>(
initialState: (() => S) | S,
): [S, Dispatch<BasicStateAction<S>>] {
return useReducer(
basicStateReducer,
(initialState: any),
);
}
Итак, ища реализацию useReducer
, мы видим, что функция установки - это функция dispatch
, которая меняется в зависимости от жизненного цикла, в котором мы сейчас находимся.
export function useReducer<S, I, A>(
reducer: (S, A) => S,
initialArg: I,
init?: I => S,
): [S, Dispatch<A>] {
...
// dispatch depends on lifecycle
return [..., dispatch];
}
}
Вы можете увидеть полную реализацию useReducer
здесь.
Для детальной реализации вам следует попробовать создать свой собственный React, что в конечном итоге приведет к упрощенная версия этого крючка:
function useState(initial) {
const oldHook =
wipFiber.alternate &&
wipFiber.alternate.hooks &&
wipFiber.alternate.hooks[hookIndex];
const hook = {
state: oldHook ? oldHook.state : initial,
queue: []
};
const actions = oldHook ? oldHook.queue : [];
actions.forEach(action => {
hook.state = action(hook.state);
});
const setState = action => {
hook.queue.push(action);
wipRoot = {
dom: currentRoot.dom,
props: currentRoot.props,
alternate: currentRoot
};
nextUnitOfWork = wipRoot;
deletions = [];
};
wipFiber.hooks.push(hook);
hookIndex++;
return [hook.state, setState];
}
Проще говоря: каждый крючок сохраняется в массиве хуков React (вот почему порядок вызовов важен, потому что хуки сохраняются в индексах массива - см. Правила хуков), и в зависимости от индекса хуков при каждом вызове он изменяет объект состояния, связанный с текущий компонент.
person
Dennis Vash
schedule
07.12.2020
[s, setS]
этого массива? - person Md. Abu Sayed   schedule 07.12.2020setS
функция и механизм[s, setS]
были бы для меня бонусом - person Subrato Patnaik   schedule 07.12.2020