Детали реализации функции setStateVariable в хуке useState

Мы знаем, что useState - это ловушка в FC, которая возвращает массив, состоящий из двух элементов. Первый - это переменная состояния, а второй - функция для обновления переменной состояния.

const initialStateVariableValue = 0; // any primitive value
const [StateVariable, setStateVariable] = useState(initialStateVariableValue);

Здесь я хотел бы узнать, каковы детали реализации функции setStateVariable? Как он обновляет переменную состояния?


person Subrato Patnaik    schedule 07.12.2020    source источник
comment
вы имеете в виду основной механизм [s, setS] этого массива?   -  person Md. Abu Sayed    schedule 07.12.2020
comment
только setS функция и механизм [s, setS] были бы для меня бонусом   -  person Subrato Patnaik    schedule 07.12.2020
comment
Вы можете ответить на этот вопрос: stackoverflow.com/questions/53895455/   -  person Md. Abu Sayed    schedule 07.12.2020


Ответы (1)


Если вы проверите реализацию на 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
comment
так что setState - это действие отправки, но все же я не понял, какова фактическая реализация этого действия отправки. Не могли бы вы мне с этим помочь? - person Subrato Patnaik; 07.12.2020
comment
Фактическая реализация на самом деле смотрит на исходный код, какого ответа вы ожидаете? - person Dennis Vash; 07.12.2020