4届中国前端开发者大会 · 2019. 5. 13. · react class-component 只用到了 es2015 class...

46
第4届中国前端开发者大会 React-Hooks: 从设计理念到实战经验 演讲者:李子翔

Upload: others

Post on 19-Aug-2020

14 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

第4届中国前端开发者大会

React-Hooks: 从设计理念到实战经验

演讲者:李子翔

Page 2: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

目录 CONTENTS React-Hooks 出现的背景

React-hooks 实战

React-Hooks 使用中的问题

探索 React-Hooks 内部

Page 3: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

1 React-Hooks 出现的背景class-component 的问题

class-component 只是过度方案

Page 4: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

在组件之间复用有状态逻辑很困难

如果你使用过 React 一段时间,你也许会熟悉一些解决此类问题的方案,比如 render props 和 hoc。但是这类方案需要重新组织你的组件结构,这可能会很麻烦,使代码难以理解。

Page 5: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

组件复杂后变得难以理解

相互关联且需要对照修改的代码被进行了拆分,而完全不相关的代码却在同一个方法中组合在一起。

Page 6: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

class-component 是过度方案

React class-component 只用到了 ES2015 class 最初级的特性

然而,有了 Hooks 以后,我们几乎就不需要 super 和 this 了

Page 7: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

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

2 React-hooks 实战本次实战将演示

从Class-Component转变到Hooks再到Custom-Hooks的写法

Page 9: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

Demo效果预览

本案例包含了监听窗口变化、监听

鼠标移动事件、监听Hash变化、使

用Context 来传递国际化数据,并

教大家如何从Class-Component迁

移到Hooks上,最终再抽取出

Custom Hooks来进行代码的复用。

Demo效果

Demo源码

Page 10: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

应用的主体结构

分别使用 3种 写法的组件来实现效果

监听Hash变化来呈现不同的实现

使用Context来传递国际化数据

Page 11: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

Class-Component

更新Document Title定义State

处理窗口Resize事件 处理鼠标移动事件

Page 12: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

Class-Component 中生命周期的处理

组件加载完成后:

更新Document Title

监听 Resize事件

监听 Mouse Move 事件

组件更新时:

更新Document Title

组件销毁前:

移除事件监听

Page 13: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

Render 函数

获取数据

根据位置计算Css3属性

遍历出人物卡片

Page 14: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

改写为Hooks

初始化状态

Page 15: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

改写为Hooks

更新Title

Page 16: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

改写为Hooks

处理Resize事件

Page 17: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

改写为Hooks

处理鼠标移动事件

Page 18: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

Return的组件

虽然使用了Hooks改写了我们

的组件,但是并没有解决核心

问题:状态逻辑的复用

Page 19: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

使用 Custom-Hooks 后的 Card 组件

状态与UI的界线变的清晰

我们只需要使用useXXX来得到

数据。

通过Custom-Hooks我们可以

在现有的所有组件中引用他们,

实现状态逻辑的复用。

Page 20: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

useMousePosition

Page 21: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

useWindowSize

Page 22: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

Custom-Hooks 中使用其他 Custom-Hooks

Page 23: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

3 React-Hooks使用中的问题

Hooks FAQ

Page 24: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

闭包陷阱

Demo地址

Page 25: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

闭包陷阱

Page 26: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

Class Component 会不会有同样的问题呢

Page 27: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

Class Component

Page 28: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

Hook 的解决方案

我们需要一个类似Class中this的功能

这个时候我们可以使用一个Ref来保存可

变的变量,并对它进行读写

Page 29: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

Class 里也存在闭包陷阱

通过闭包的方式来访问count,在

Alert时候就是render时得到的那个

数值

因此,闭包陷阱并不是 React-Hooks

自身的问题,而是React-Hooks要求

开发者对闭包需要有更深刻的理解。

Page 30: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

setInterval or useInterval

通过观察,我们可以发现

右边的代码会有个Bug

Page 31: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

setInterval or useInterval

虽然我们可以通过

setCount传入一个函数去

更新count,但是这么做

在一个复杂场景中可能不

适用,并不是我们最终想

要的。

Page 32: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

setInterval or useInterval

useInterval的实现

我们的delay可以动态调整

并且传入一个负数后可以暂停我

们的定时器 Demo地址

Page 33: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

setInterval or useInterval

这才是我们想要的版本

Page 34: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

setInterval or useInterval

来看下我们的Hooks 版本

Page 35: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

setInterval or useInterval

在Class-Component中我们要如何实现呢?

Page 36: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

useInterval 实战

这个消息数量组件在中后台项目中很常见

现在我们可以使用 useInterval 去轮询接口,获取消息数量了

但是,我们只要无脑用定时器去轮询接口就可以了吗?

Page 37: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

useInterval + useVisibility

如果我们同时打开了多个含有消息通知的页面,但当前仅有一个Tab是可见的

这个时候我们的页面不应该无脑轮询调用接口,浪费性能和资源

现在我们就需要实现一个 useVisibility 的 Custom-Hooks 来组合使用了

Page 38: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

useVisibility的实现

Page 39: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

useInterval + useVisibility

那现在我们只要把 2个 Custom-

Hooks 组合使用 或者 重新组合

成一个 useIntervalOnVisibile

就实现了我们想要的效果了

Page 40: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

useInterval + useVisibility

但是,现在我们只要把 2个 Custom-Hook 重新组合成一个

useIntervalOnVisibile 就完事了吗?

假设我们轮询的间隔为 30s,当页面不可见的时候我们暂停我们

的轮询,1分钟后 我们重新回到了当前Tab,这时我们的请求应

该立即发出,而不是在30s后请求数据,这又该如何实现呢?

事情远远没有这么简单!

Page 41: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

4 探索 React-Hooks 内部以 useState 和 useReducer 为例

Page 42: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

如何用 useState

实现简易版的 useReducer

Page 43: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

如何用 useReducer

实现简易版的 useState

Page 44: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

React内部真正的调用

Page 45: 4届中国前端开发者大会 · 2019. 5. 13. · React class-component 只用到了 ES2015 class 最初级的特性 然而,有了 Hooks 以后,我们几乎就不需要 super

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

THANK YOU

李子翔@Ctrip

Q&A