![Page 1: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/1.jpg)
第4届中国前端开发者大会
React-Hooks: 从设计理念到实战经验
演讲者:李子翔
![Page 2: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/2.jpg)
目录 CONTENTS React-Hooks 出现的背景
React-hooks 实战
React-Hooks 使用中的问题
探索 React-Hooks 内部
![Page 3: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/3.jpg)
1 React-Hooks 出现的背景class-component 的问题
class-component 只是过度方案
![Page 4: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/4.jpg)
在组件之间复用有状态逻辑很困难
如果你使用过 React 一段时间,你也许会熟悉一些解决此类问题的方案,比如 render props 和 hoc。但是这类方案需要重新组织你的组件结构,这可能会很麻烦,使代码难以理解。
![Page 5: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/5.jpg)
组件复杂后变得难以理解
相互关联且需要对照修改的代码被进行了拆分,而完全不相关的代码却在同一个方法中组合在一起。
![Page 6: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/6.jpg)
class-component 是过度方案
React class-component 只用到了 ES2015 class 最初级的特性
然而,有了 Hooks 以后,我们几乎就不需要 super 和 this 了
![Page 7: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/7.jpg)
class-component 是过度方案
不建议组件继承非 React.Component | React.PureComponent
React 推崇 HOC 和组合的方式,而不是继承的方式来扩展组件
组合更适合React的风格,因为React是基于组件的
因此 React 从未把 class-component 视为最终的组件定义方式
![Page 8: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/8.jpg)
2 React-hooks 实战本次实战将演示
从Class-Component转变到Hooks再到Custom-Hooks的写法
![Page 9: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/9.jpg)
Demo效果预览
本案例包含了监听窗口变化、监听
鼠标移动事件、监听Hash变化、使
用Context 来传递国际化数据,并
教大家如何从Class-Component迁
移到Hooks上,最终再抽取出
Custom Hooks来进行代码的复用。
Demo效果
Demo源码
![Page 10: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/10.jpg)
应用的主体结构
分别使用 3种 写法的组件来实现效果
监听Hash变化来呈现不同的实现
使用Context来传递国际化数据
![Page 11: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/11.jpg)
Class-Component
更新Document Title定义State
处理窗口Resize事件 处理鼠标移动事件
![Page 12: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/12.jpg)
Class-Component 中生命周期的处理
组件加载完成后:
更新Document Title
监听 Resize事件
监听 Mouse Move 事件
组件更新时:
更新Document Title
组件销毁前:
移除事件监听
![Page 13: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/13.jpg)
Render 函数
获取数据
根据位置计算Css3属性
遍历出人物卡片
![Page 14: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/14.jpg)
改写为Hooks
初始化状态
![Page 15: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/15.jpg)
改写为Hooks
更新Title
![Page 16: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/16.jpg)
改写为Hooks
处理Resize事件
![Page 17: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/17.jpg)
改写为Hooks
处理鼠标移动事件
![Page 18: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/18.jpg)
Return的组件
虽然使用了Hooks改写了我们
的组件,但是并没有解决核心
问题:状态逻辑的复用
![Page 19: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/19.jpg)
使用 Custom-Hooks 后的 Card 组件
状态与UI的界线变的清晰
我们只需要使用useXXX来得到
数据。
通过Custom-Hooks我们可以
在现有的所有组件中引用他们,
实现状态逻辑的复用。
![Page 20: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/20.jpg)
useMousePosition
![Page 21: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/21.jpg)
useWindowSize
![Page 22: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/22.jpg)
Custom-Hooks 中使用其他 Custom-Hooks
![Page 25: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/25.jpg)
闭包陷阱
![Page 26: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/26.jpg)
Class Component 会不会有同样的问题呢
![Page 27: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/27.jpg)
Class Component
![Page 28: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/28.jpg)
Hook 的解决方案
我们需要一个类似Class中this的功能
这个时候我们可以使用一个Ref来保存可
变的变量,并对它进行读写
![Page 29: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/29.jpg)
Class 里也存在闭包陷阱
通过闭包的方式来访问count,在
Alert时候就是render时得到的那个
数值
因此,闭包陷阱并不是 React-Hooks
自身的问题,而是React-Hooks要求
开发者对闭包需要有更深刻的理解。
![Page 30: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/30.jpg)
setInterval or useInterval
通过观察,我们可以发现
右边的代码会有个Bug
![Page 31: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/31.jpg)
setInterval or useInterval
虽然我们可以通过
setCount传入一个函数去
更新count,但是这么做
在一个复杂场景中可能不
适用,并不是我们最终想
要的。
![Page 32: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/32.jpg)
setInterval or useInterval
useInterval的实现
我们的delay可以动态调整
并且传入一个负数后可以暂停我
们的定时器 Demo地址
![Page 33: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/33.jpg)
setInterval or useInterval
这才是我们想要的版本
![Page 34: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/34.jpg)
setInterval or useInterval
来看下我们的Hooks 版本
![Page 35: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/35.jpg)
setInterval or useInterval
在Class-Component中我们要如何实现呢?
![Page 36: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/36.jpg)
useInterval 实战
这个消息数量组件在中后台项目中很常见
现在我们可以使用 useInterval 去轮询接口,获取消息数量了
但是,我们只要无脑用定时器去轮询接口就可以了吗?
![Page 37: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/37.jpg)
useInterval + useVisibility
如果我们同时打开了多个含有消息通知的页面,但当前仅有一个Tab是可见的
这个时候我们的页面不应该无脑轮询调用接口,浪费性能和资源
现在我们就需要实现一个 useVisibility 的 Custom-Hooks 来组合使用了
![Page 38: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/38.jpg)
useVisibility的实现
![Page 39: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/39.jpg)
useInterval + useVisibility
那现在我们只要把 2个 Custom-
Hooks 组合使用 或者 重新组合
成一个 useIntervalOnVisibile
就实现了我们想要的效果了
![Page 40: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/40.jpg)
useInterval + useVisibility
但是,现在我们只要把 2个 Custom-Hook 重新组合成一个
useIntervalOnVisibile 就完事了吗?
假设我们轮询的间隔为 30s,当页面不可见的时候我们暂停我们
的轮询,1分钟后 我们重新回到了当前Tab,这时我们的请求应
该立即发出,而不是在30s后请求数据,这又该如何实现呢?
事情远远没有这么简单!
![Page 41: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/41.jpg)
4 探索 React-Hooks 内部以 useState 和 useReducer 为例
![Page 42: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/42.jpg)
如何用 useState
实现简易版的 useReducer
![Page 43: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/43.jpg)
如何用 useReducer
实现简易版的 useState
![Page 44: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/44.jpg)
React内部真正的调用
![Page 45: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/45.jpg)
React-hooks 解决了什么问题
React 一直在探索如何实现分离业务逻辑代码,复用组件内的业务逻辑
Hooks 是现阶段的一个有效解决方案,既避免了 class component 的问题,又增强了 function component 的能力
Hooks 允许我们写 custom hook,使我们得到了除了组件以外的新的组合维度——状态和业务逻辑的组合
以后的 React 项目里,除了 components/ 目录以外,将增加 hooks/ 目录
Hooks 与即将到来的 React-Suspense 和 React-ConcurrentMode 的互相配合,也将释放更多的想象力,让我们拭目以待
![Page 46: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super](https://reader035.vdocument.in/reader035/viewer/2022062223/5fc301acc2c5ed298e04b29c/html5/thumbnails/46.jpg)
THANK YOU
李子翔@Ctrip
Q&A