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