Reactjs useState钩子中setStateVariable函数的实现细节

Reactjs useState钩子中setStateVariable函数的实现细节,reactjs,use-state,Reactjs,Use State,我们知道,useState是FC中的一个钩子,它返回由两个元素组成的数组。第一个是状态变量,第二个是更新状态变量的函数 const initialStateVariableValue = 0; // any primitive value const [StateVariable, setStateVariable] = useState(initialStateVariableValue); 这里我想知道setStateVariable函数的实现细节是什么?它是如何更新状态变量的?如果您检查

我们知道,
useState
是FC中的一个钩子,它返回由两个元素组成的数组。第一个是状态变量,第二个是更新状态变量的函数

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

这里我想知道
setStateVariable
函数的实现细节是什么?它是如何更新状态变量的?

如果您检查了上面的实现,您会注意到
useState
只是用一个基本的减速机调用
useReducer

export function useState<S>(
  initialState: (() => S) | S,
): [S, Dispatch<BasicStateAction<S>>] {
  return useReducer(
    basicStateReducer,
    (initialState: any),
  );
}
您可以看到完整的
useReducer
实现

对于详细的实现,您应该尝试并最终实现此钩子的简化版本:

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 hooks array”中(这就是为什么调用顺序很重要,因为钩子保存在数组的索引中-请参见钩子规则),并且根据钩子的索引,每当调用钩子时,它都会改变与当前组件关联的状态对象。

您是指
[s,set]的主要机制吗
这个数组?只有
设置
函数和
[s,set]
的机制对我来说是一个额外的好处。你可以回答这个问题:所以setState是一个分派操作,但我仍然不知道分派操作的实际实现是什么。你能帮我吗?实际的实现实际上是在看源代码,你希望得到什么答案?
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];
}