ReactHooks学习

本文介绍了React hooks的使用原则,强调只在React函数中调用,且不要在循环、条件或嵌套函数中调用,以确保每次渲染时执行顺序一致。还以useState为例,分析其调用链路,指出Hooks底层依赖顺序链表,首次渲染构建链表,更新时遍历链表,本质是链表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

React hooks 的使用原则

  1. 只在React 函数中调用Hook
  2. 不要再循环、条件或嵌套函数中调用Hook

1、为什么“不要再循环、条件或嵌套函数中调用Hook

为了确保Hooks在每次渲染时都保持同样的执行顺序

2、 Hooks 的正常运作,在底层依赖于顺序链表

以 useState 为例,分析 React-Hooks 的调用链路

hooks 首次渲染
hooks 首次渲染
mountState源码

mounState 的主要工作是初始化 Hooks

// 进入 mounState 逻辑
function mountState(initialState) {
  // 将新的 hook 对象追加进链表尾部
  var hook = mountWorkInProgressHook();
  // initialState 可以是一个回调,若是回调,则取回调执行后的值
  if (typeof initialState === 'function') {
    // $FlowFixMe: Flow doesn't like mixed types
    initialState = initialState();
  }
  // 创建当前 hook 对象的更新队列,这一步主要是为了能够依序保留 dispatch
  const queue = hook.queue = {
    last: null,
    dispatch: null,
    lastRenderedReducer: basicStateReducer,
    lastRenderedState: (initialState: any),
  };
  // 将 initialState 作为一个“记忆值”存下来
  hook.memoizedState = hook.baseState = initialState;
  // dispatch 是由上下文中一个叫 dispatchAction 的方法创建的,这里不必纠结这个方法具体做了什么
  var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
  // 返回目标数组,dispatch 其实就是示例中常常见到的 setXXX 这个函数
  return [hook.memoizedState, dispatch];
}

mountWorkInProgressHook 方法的源码

function mountWorkInProgressHook() {
  // 注意,单个 hook 是以对象的形式存在的
  var hook = {
    memoizedState: null,
    baseState: null,
    baseQueue: null,
    queue: null,
    next: null
  };
  if (workInProgressHook === null) {
    // 这行代码每个 React 版本不太一样,但做的都是同一件事:将 hook 作为链表的头节点处理
    firstWorkInProgressHook = workInProgressHook = hook;
  } else {
    // 若链表不为空,则将 hook 追加到链表尾部
    workInProgressHook = workInProgressHook.next = hook;
  }
  // 返回当前的 hook
  return workInProgressHook;
}

结论: hook 相关的所有信息收敛在一个 hook 对象里,而 hook 对象之间以单向链表的形式相互串联。

hooks 更新过程

更新过程做的事情:按顺序去遍历之前构建好的链表,取出对应的数据信息进行渲染

hooks 更新过程

总结

1、 mountState(首次渲染)构建链表并渲染;updateState 依次遍历链表并渲染
2、 hooks 的渲染是通过“依次遍历”来定位每个 hooks 内容的。如果前后两次读到的链表在顺序上出现差异,那么渲染的结果是不可控的
3、Hooks 的本质是链表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值