千家信息网

关于useState的知识点有哪些

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本篇内容介绍了"关于useState的知识点有哪些"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!ho
千家信息网最后更新 2026年11月02日关于useState的知识点有哪些

本篇内容介绍了"关于useState的知识点有哪些"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

hook如何保存数据

FunctionComponent的render本身只是函数调用。

那么在render内部调用的hook是如何获取到对应数据呢?

比如:

  • useState获取state

  • useRef获取ref

  • useMemo获取缓存的数据

答案是:

每个组件有个对应的fiber节点(可以理解为虚拟DOM),用于保存组件相关信息。

每次FunctionComponent render时,全局变量currentlyRenderingFiber都会被赋值为该FunctionComponent对应的fiber节点。

所以,hook内部其实是从currentlyRenderingFiber中获取状态信息的。

多个hook如何获取数据

我们知道,一个FunctionComponent中可能存在多个hook,比如:

function App() {    // hookA    const [a, updateA] = useState(0);    // hookB   const [b, updateB] = useState(0);    // hookC    const ref = useRef(0);    return 

; }

那么多个hook如何获取自己的数据呢?

答案是:

currentlyRenderingFiber.memoizedState中保存一条hook对应数据的单向链表。

对于如上例子,可以理解为:

const hookA = {    // hook保存的数据    memoizedState: null,    // 指向下一个hook    next: hookB    // ...省略其他字段  }; hookB.next = hookC;  currentlyRenderingFiber.memoizedState = hookA;

当FunctionComponent render时,每执行到一个hook,都会将指向currentlyRenderingFiber.memoizedState链表的指针向后移动一次,指向当前hook对应数据。

这也是为什么React要求hook的调用顺序不能改变(不能在条件语句中使用hook) —— 每次render时都是从一条固定顺序的链表中获取hook对应数据的。

useState执行流程

我们知道,useState返回值数组第二个参数为改变state的方法。

在源码中,他被称为dispatchAction。

每当调用dispatchAction,都会创建一个代表一次更新的对象update:

const update = {    // 更新的数据    action: action,    // 指向下一个更新    next: null  };

对于如下例子

function App() {    const [num, updateNum] = useState(0);    function increment() {      updateNum(num + 1);    }    return 

{num}

; }

调用updateNum(num + 1),会创建:

const update = {    // 更新的数据    action: 1,    // 指向下一个更新    next: null    // ...省略其他字段  };

如果是多次调用dispatchAction,例如:

function increment() {    // 产生update1    updateNum(num + 1);    // 产生update2    updateNum(num + 2);    // 产生update3    updateNum(num + 3);  }

那么,update会形成一条环状链表。

update3 --next--> update1    ^                 |    |               update2    |______next_______|

这条链表保存在哪里呢?

既然这条update链表是由某个useState的dispatchAction产生,那么这条链表显然属于该useState hook。

我们继续补充hook的数据结构。

const hook = {    // hook保存的数据    memoizedState: null,    // 指向下一个hook    next: hookForB    // 本次更新以baseState为基础计算新的state    baseState: null,    // 本次更新开始时已有的update队列    baseQueue: null,    // 本次更新需要增加的update队列    queue: null,  };

其中,queue中保存了本次更新update的链表。

在计算state时,会将queue的环状链表剪开挂载在baseQueue最后面,baseQueue基于baseState计算新的state。

在计算state完成后,新的state会成为memoizedState。

为什么更新不基于memoizedState而是baseState,是因为state的计算过程需要考虑优先级,可能有些update优先级不够被跳过。所以memoizedState并不一定和baseState相同。更详细的解释见React技术揭秘[1]

回到我们开篇第一个问题:

function App() {    const [num, updateNum] = useState(0);    window.updateNum = updateNum;    return num;  }

调用window.updateNum(1)可以将视图中的0更新为1么?

我们需要看看这里的updateNum方法的具体实现:

updateNum === dispatchAction.bind(null, currentlyRenderingFiber, queue);

可见,updateNum方法即绑定了currentlyRenderingFiber与queue(即hook.queue)的dispatchAction。

上文已经介绍,调用dispatchAction的目的是生成update,并插入到hook.queue链表中。

既然queue作为预置参数已经绑定给dispatchAction,那么调用dispatchAction就步仅局限在FunctionComponent内部了。

update的action

第二个问题

function App() {    const [num, updateNum] = useState(0);    function increment() {      setTimeout(() => {        updateNum(num + 1);      }, 1000);    }    return 

{num}

; }

在1秒内快速点击p5次,视图上显示为几?

我们知道,调用updateNum会产生update,其中传参会成为update.action。

在1秒内点击5次。在点击第五次时,第一次点击创建的update还没进入更新流程,所以hook.baseState还未改变。

那么这5次点击产生的update都是基于同一个baseState计算新的state,并且num变量也还未变化(即5次update.action(即num + 1)为同一个值)。

所以,最终渲染的结果为1。

useState与useReducer

那么,如何5次点击让视图从1逐步变为5呢?

由以上知识我们知道,需要改变baseState或者action。

其中baseState由React的更新流程决定,我们无法控制。

但是我们可以控制action。

action不仅可以传值,也可以传函数。

// action为值  updateNum(num + 1);  // action为函数  updateNum(num => num + 1);

在基于baseState与update链表生成新state的过程中:

let newState = baseState;  let firstUpdate = hook.baseQueue.next;  let update = firstUpdate; // 遍历baseQueue中的每一个update  do {    if (typeof update.action === 'function') {      newState = update.action(newState);    } else {      newState = action;    }  } while (update !== firstUpdate)

可见,当传值时,由于我们5次action为同一个值,所以最终计算的newState也为同一个值。

而传函数时,newState基于action函数计算5次,则最终得到累加的结果。

如果这个例子中,我们使用useReducer而不是useState,由于useReducer的action始终为函数,所以不会遇到我们例子中的问题。

事实上,useState本身就是预置了如下reducer的useReducer。

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

"关于useState的知识点有哪些"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

数据 更新 函数 指向 知识 例子 多个 方法 流程 视图 过程 问题 知识点 优先级 会创 信息 内容 参数 变量 字段 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 亿人帮互联网科技有限公司 深圳九邦互联网科技有限公司 新华互联网科技学校 互联网科技公司华为 互联网下的科技发展 互联网金融公司科技 互联网女皇 腾讯科技 开启互联网科技时代小说 晓花互联网科技有限公司网址 苏州铭阳互联网科技有限公司 速维有品互联网信息科技(苏州)有限公司 中国互联网公司排名锤子科技 爱医互联网络科技 科技大学互联网 互联网科技快讯热点 互联网硬科技公司 版纳互联网科技选哪家 科技互联网公司两年变化 平安好医生打造互联网科技医疗 互联网科技创新方面的资料 博彦科技互联网金融 互联网佳科技有限公司 没上市的科技互联网公司 北京互联网科技 无线互联网科技 华中科技有哪些互联网大佬 江阴互联网智能科技产品进口 上海钢联属于互联网科技股吗 2021世界互联网领先科技成果发布 唐山双旺合互联网科技产业园
0