React调用setState触发重渲染后会重新执行useState初始化吗?
useState 重渲染不重置状态的核心运行逻辑 你产生这个疑问的核心误区是默认了组件函数重渲染时,useState 会完整执行初始化逻辑,但实际上React对Hook的状态做了独立于组件函数作用域的托管:
- React在每个组件对应的Fiber节点(可以理解为React内部维护的组件实例描述对象)上,专门开辟了存储Hook状态的链表结构,每个
useState调用对应链表上的一个存储单元,组件首次挂载时才会写入初始值。 - 组件重渲染时,React会严格按照Hook的调用顺序,依次从已经存在的状态链表中读取上一次留存的状态值返回,你写在
useState()括号里的初始值(包括初始化函数)在非首次挂载的渲染流程中会被直接忽略,根本不会参与赋值。
以你提到的计数器场景为例,完整执行流程如下:
- 组件首次挂载渲染:React执行组件函数,遇到
useState(0),检测到当前是组件第一次渲染,就把初始值0写入该Hook对应的状态存储单元,返回状态值0和对应的setState方法。- 调用
setState(1):React接收到状态更新请求,先把对应状态存储单元里的值更新为1,再标记当前组件需要重渲染。- 组件重渲染:React重新执行组件函数,再次遇到
useState(0),检测到当前不是首次挂载,直接跳过初始值读取逻辑,从对应状态存储单元里拿出已经更新好的1返回,所以你拿到的状态是更新后的值,不会被重置为0。
补充一个相关的特性佐证这个逻辑:如果你给useState传入函数作为初始值(比如useState(() => 计算量很大的初始值生成逻辑)),这个初始化函数也只会在组件首次挂载时执行一次,后续重渲染不会重复调用,就是因为非首次渲染时React根本不会处理初始值相关的逻辑。
另外React要求Hook不能写在条件判断、循环、嵌套函数里,本质也是因为React是靠Hook的调用顺序来匹配对应的状态存储单元,一旦不同渲染流程中Hook的调用顺序变了,就会出现状态匹配错乱的问题。
内容的提问来源于stack exchange,提问作者ezio
相关产品推荐
相关产品推荐

