hooks-useState

hooks-useState

案例

function FunctionComponent(props) {
  // 
  const [state, dispatch] = useState(1);

  return (
    <div className="border">
      <p onClick={()=>{
        dispatch(2);
      }}>{props.name}{state}</p>
    </div>
  );
}

同理前面useReducer的流程,核心看useState的mount和update。

mountState
function mountState(initialState) {
  var hook = mountWorkInProgressHook();

  if (typeof initialState === 'function') {
    initialState = initialState();
  }
	// 初始值给到hook链的memoizedState
  hook.memoizedState = hook.baseState = initialState;
  var queue = hook.queue = {
    pending: null,
    dispatch: null,
    lastRenderedReducer: basicStateReducer,// 需要重点关注
    lastRenderedState: initialState
  };
    // 初始化绑定,当前的fiber节点和合并链
  var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
  return [hook.memoizedState, dispatch];
}

basicStateReducer

这个函数和后续更新有关系。初始化时只是绑定上了。

function basicStateReducer(state, action) {
    
  return typeof action === 'function' ? action(state) : action;
}

dispatchAction

更新时的入口,和useReducer的dispatchAction时一摸一样的,只不过这里的话会有不同的解读。

fiber和quene时我们绑定时传入的参数,userState的 action 是我们在调用dispatch的时候传过来的函数或者其他数据。所以basicStateReducer得到的是函数就执行得到结果,是其他的数据直接返回。

function dispatchAction(fiber, queue, action) {
  {
    if (typeof arguments[3] === 'function') {
      error("State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().');
    }
  }

  var eventTime = requestEventTime();
  var lane = requestUpdateLane(fiber);
    // update 循环链表,会存储state,合并state更新,也就是说我们在同一个地方多次设置state的值时,会在整个update扫描完毕之后再去做更新。
  var update = {
    lane: lane,
    action: action,
    eagerReducer: null,
    eagerState: null,
    next: null
  }; // Append the update to the end of the list.

  var pending = queue.pending;

  if (pending === null) {
    // This is the first update. Create a circular list.
    update.next = update;
  } else {
    update.next = pending.next;
    pending.next = update;
  }

  queue.pending = update;
  var alternate = fiber.alternate;

  if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
   
    didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true;
  } else {
    if (fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes)) {
      
      var lastRenderedReducer = queue.lastRenderedReducer;

      if (lastRenderedReducer !== null) {
        var prevDispatcher;

        {
          prevDispatcher = ReactCurrentDispatcher$1.current;
          ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
        }

        try {
          var currentState = queue.lastRenderedState;
            // 这里额外处理
          var eagerState = lastRenderedReducer(currentState, action); // 

          update.eagerReducer = lastRenderedReducer;
          update.eagerState = eagerState;

          if (objectIs(eagerState, currentState)) {
          
            return;
          }
        } catch (error) {
        } finally {
          {
            ReactCurrentDispatcher$1.current = prevDispatcher;
          }
        }
      }
    }

    {
      if ('undefined' !== typeof jest) {
        warnIfNotScopedWithMatchingAct(fiber);
        warnIfNotCurrentlyActingUpdatesInDev(fiber);
      }
    }

    scheduleUpdateOnFiber(fiber, lane, eventTime);
  }
}

updateState

更新走的是useReducer的逻辑,只不过是将basicStateReducer当作action传递给updateReducer,updateReducer中获取update的action,得到值

function updateState(initialState) {
  return updateReducer(basicStateReducer);
}

写在最后

useState可以看作是一个useReducer,借用的userReducer去保存数据到fiber上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值