You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
现在 React 提供给 functional component 维护 local state 的 api 只有一个 useState。跟 class component 中 setState 不同的是:setState 将所有数据存储在一个对象中,调用其进行更新时,更新后的 state 和旧有 state 做浅合并;而 useState 提供了一个选项把每个 state 单值分别存储,再加上还有其他 hooks api,比如说 useEffect、useReducer 和 useContext 等,而且需要维护所有 hooksapirender 时的状态,是不是单链表更好呢。是否有更合适的数据结构用来存储 hooks,暂时想不到
昨天 司徒正美 过世,据传病因为颈椎病,本人无处证实其真实病因。说是屌丝逆袭的典范,虽早已脱离穷的状态,仍然与人合租,生活简朴,一件冬衣穿多年,关心社会,具有责任感。R.I.P.愿大家都能珍惜当下,积极乐观生活,不留遗憾。
入口为 详见 packages/react-reconciler/src/ReactFiberHooks.js 中的 renderWithHooks 函数,下面主要从组件的生命周期中比较重要的 mount 和 update 分析
hooks
api 中的useState
和useEffect
。术语表
hooks
api (useState
/useEffect
等)存储结构
采用 单链表 结构在 mount 函数组件时根据
hooks
api 的调用顺序进行初始化(详见 packages/react-reconciler/src/ReactFiberHooks.js 中的 mountWorkInProgressHook 函数)其中 memoizedState 字段存储 state 值(
useState
),或者 effect 相关信息(useEffect
);next 指向下一个hooks
节点;queue 在useState
下存储 dispatch 函数和fiber
队列。fiber
节点存储类型hooks
相关数据存储在 fiber 节点下的 memoizedState 字段下。useState
节点存储类型useEffect
节点存储类型阶段
mount
在 mount 阶段,每调用一次
hooks
api 都会按照顺序初始化单链表(详见 packages/react-reconciler/src/ReactFiberHooks.js 中的 mountWorkInProgressHook 函数)update
在 update 阶段,每调用一次
hooks
api 都会从单链表中取已经存储的hook
节点数据(详见 packages/react-reconciler/src/ReactFiberHooks.js 中的 updateWorkInProgressHook 函数),useState
取出 memoizedState 和 queue.dispatch。源码调试
使用 create-react-app 创建项目,
React
基于 16.3.1 版本,node_moduels 下面的react
&react-dom
目录下的 cjs/*(react/react-dom).development.js 直接 debug,可以直接克隆项目进行调试。简单实现一个
hooks
以下代码只是简单实现了一个 mount 和 update 初始化和更新的操作
后续
FAQ
官方文档 其实已经介绍的非常详细了,常见问题 也已经总结的很全面。在这里主要从源码的角度上详细讲几个为什么要这样设计的原因(官方文档上很多是讲如果不这样做,会有怎样的问题,没有明确指出为什么)。
为什么使用单链表形式存储
hooks
?现在
React
提供给 functional component 维护 local state 的 api 只有一个useState
。跟 class component 中setState
不同的是:setState
将所有数据存储在一个对象中,调用其进行更新时,更新后的 state 和旧有state
做浅合并;而useState
提供了一个选项把每个state
单值分别存储,再加上还有其他hooks
api,比如说useEffect
、useReducer
和useContext
等,而且需要维护所有hooks
api render 时的状态,是不是单链表更好呢。是否有更合适的数据结构用来存储hooks
,暂时想不到为什么在使用 函数 进行初始化
useState
时,可以做到惰性执行?首先,无论是表达式还是函数都是作为
useState
的参数存在的,表达式作为形参来传递,每次函数调用都会运行表达式(详见 packages/react-reconciler/src/ReactFiberHooks.js 中的 updateState 函数)。看下面的例子,可能理解起来就没有那么困难了。以上分析是按照个人认为能够理解的脉络阐述的,如果您认为哪里比较混乱,欢迎与我联系。如果哪里有理解上的错误,请一定帮忙指出。如果您也有阅读源码的兴趣,欢迎一起交流。
The text was updated successfully, but these errors were encountered: