React Hook源码解析(三)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: React Hook源码解析(三)

640.jpg

写在前面


React Hook源码解析(一)


React Hook源码解析(二)


前两篇文章,深入了Hook的源码。本文将以useStateuseEffect为主,总结一下Hook的相关内容,


const App = () => {
    const [title, setTitle] = useState('');    const [fontSize, setFontSize] = useState('13');
    useEffect(() => {       document.title = title;    },[title]);
    useEffect(() => {        document.body.style.fontSize = `${fontSize}px`;    }, [fontSize]);
    return <React.Fragment>        <input value={title} onChange={e => setTitle(e.target.value)} />        <input value={fontSize} onChange={e => setFontSize(e.target.value)} />        <p>Hello World</p>    </React.Fragment>};


组件初次挂载

640.png


组件首次挂载的时候,依次执行四行useXXX的代码,生成4个hook对象,按照顺序形成完整的hook链,挂载在Fiber对象的memorizedState属性上。hook对象上的memorizedState属性表示当前hook对象的值。对于effect-hook,其memorizedState属性的值为一个对象(effect对象),包含了一个指向下一下effect-hook的effect对象的指针,会形成一个环形链表。


组件更新


对于state-hook,其setState函数通过闭包保存了对应的hook对象的引用。调用setState对状态值进行更新时,每调用一次setState,都会修改hook对象上的queue属性。queue属性保存着hook的更新信息。setState执行完后,对应的hook对象上的memorized值就是最新的了。


对于effect-hook,每次组件渲染时,都会进入effect-hook的逻辑:首先判断deps数组内的值较上一次有无变化。如果无变化,则会给该effect打上忽略的tag。如果跟上一次组件渲染时有变化,最终会先执行destory函数(即useEffect中return的函数),然后执行create函数。


对于副作用,react每次都会生成新的effect链,如果deps数组内的值变化了,那么新的effect对象还会赋值给effect-hookmemorizedState属性。


本例中,假设我们在title那里,输入了hello,组件更新完成后,Fiber节点上的hook信息如下:


640.png


总结


稍微总结一下,关于react hook,我们需要知道以下几点:

1、react hook大量采用了链表的结构。

2、代码中hook的书写顺序,决定了最终hook在fiber上的存储顺序。

3、组件每次渲染的时候,hook的代码都会执行一次,并且将上一次的hook对象都clone一遍,返回最新的hook的state以及对应的更新函数。在state的更新函数中,以闭包的形式保存了对应hook对象的引用。


写在后面


至此,react hook源码解析系列暂时告一段落了。尽管有许多地方没有我还没完全理解,有的地方也没有讲述清楚,但是对react hook的整体实现方式已经有了进一步深入的理解了。符合预期。最后,推荐一篇hook相关的文章:


https://github.com/shanggqm/blog/issues/4

相关文章
|
13天前
|
监控 网络协议 Java
Tomcat源码解析】整体架构组成及核心组件
Tomcat,原名Catalina,是一款优雅轻盈的Web服务器,自4.x版本起扩展了JSP、EL等功能,超越了单纯的Servlet容器范畴。Servlet是Sun公司为Java编程Web应用制定的规范,Tomcat作为Servlet容器,负责构建Request与Response对象,并执行业务逻辑。
Tomcat源码解析】整体架构组成及核心组件
|
1天前
|
开发工具
Flutter-AnimatedWidget组件源码解析
Flutter-AnimatedWidget组件源码解析
|
20天前
|
测试技术 Python
python自动化测试中装饰器@ddt与@data源码深入解析
综上所述,使用 `@ddt`和 `@data`可以大大简化写作测试用例的过程,让我们能专注于测试逻辑的本身,而无需编写重复的测试方法。通过讲解了 `@ddt`和 `@data`源码的关键部分,我们可以更深入地理解其背后的工作原理。
18 1
|
30天前
|
开发者 Python
深入解析Python `httpx`源码,探索现代HTTP客户端的秘密!
深入解析Python `httpx`源码,探索现代HTTP客户端的秘密!
61 1
|
30天前
|
开发者 Python
深入解析Python `requests`库源码,揭开HTTP请求的神秘面纱!
深入解析Python `requests`库源码,揭开HTTP请求的神秘面纱!
108 1
|
11天前
|
前端开发 Java UED
瞬间变身高手!JSF 与 Ajax 强强联手,打造极致用户体验的富客户端应用,让你的应用焕然一新!
【8月更文挑战第31天】JavaServer Faces (JSF) 是 Java EE 标准的一部分,常用于构建企业级 Web 应用。传统 JSF 应用采用全页面刷新方式,可能影响用户体验。通过集成 Ajax 技术,可以显著提升应用的响应速度和交互性。本文详细介绍如何在 JSF 应用中使用 Ajax 构建富客户端应用,并通过具体示例展示 Ajax 在 JSF 中的应用。首先,确保安装 JDK 和支持 Java EE 的应用服务器(如 Apache Tomcat 或 WildFly)。
23 0
|
11天前
|
前端开发 UED 开发者
React组件优化全攻略:深度解析让你的前端应用飞速运行的秘诀——从PureComponent到React.memo的彻底性能比较
【8月更文挑战第31天】在构建现代Web应用时,性能是提升用户体验的关键因素。React作为主流前端库,其组件优化尤为重要。本文深入探讨了React组件优化策略,包括使用`PureComponent`、`React.memo`及避免不必要的渲染等方法,帮助开发者显著提升应用性能。通过实践案例对比优化前后效果,不仅提高了页面渲染速度,还增强了用户体验。优化React组件是每个开发者必须关注的重点。
22 0
|
11天前
|
前端开发 JavaScript 开发者
React生命周期方法完全指南:深入理解并高效应用每个阶段的钩子——从初始化到卸载的全方位解析
【8月更文挑战第31天】本文详细介绍了React组件生命周期方法,包括初始化、挂载、更新和卸载四个阶段的关键钩子。通过探讨每个阶段的方法,如`componentDidMount`和`componentWillUnmount`,帮助开发者在正确时机执行所需操作,提升应用性能。文章还提供了最佳实践,指导如何避免常见错误并充分利用最新钩子。
19 0
|
18天前
|
前端开发 JavaScript 算法
React.useState 的更新频率及原因解析
【8月更文挑战第24天】
47 0
|
26天前
|
算法 安全 Java
深入解析Java多线程:源码级别的分析与实践
深入解析Java多线程:源码级别的分析与实践

推荐镜像

更多