Hooks 理念
::: warning 注意
在开始本章学习前,你需要了解Hooks
的基本用法。
如果你还未使用过Hooks
,可以从官方文档开始。
:::
你可以从这里了解Hooks
的设计动机。作为一名框架使用者
,了解设计动机
对于我们日常开发就足够了。
但是,为了更好的理解Hooks
的源码架构
,我们需要转换身份,以框架开发者
的角度来看待Hooks
的设计理念
。
从LOGO聊起
React
LOGO
的图案是代表原子
(atom
)的符号。世间万物由原子
组成,原子
的类型
与属性
决定了事物的外观与表现。
同样,在React
中,我们可以将UI
拆分为很多独立的单元,每个单元被称为Component
。这些Component
的属性
与类型
决定了UI
的外观与表现。
讽刺的是,原子
在希腊语中的意思为不可分割的
(indivisible
),但随后科学家在原子中发现了更小的粒子 —— 电子(electron
)。电子可以很好的解释原子
是如何工作的。
在React
中,我们可以说ClassComponent
是一类原子
。
但对于Hooks
来说,与其说是一类原子
,不如说他是更贴近事物运行规律
的电子
。
我们知道,React
的架构遵循schedule - render - commit
的运行流程,这个流程是React
世界最底层的运行规律
。
ClassComponent
作为React
世界的原子
,他的生命周期
(componentWillXXX
/componentDidXXX
)是为了介入React
的运行流程而实现的更上层抽象,这么做是为了方便框架使用者
更容易上手。
相比于ClassComponent
的更上层抽象,Hooks
则更贴近React
内部运行的各种概念(state
| context
| life-cycle
)。
作为使用React
技术栈的开发者,当我们初次学习Hooks
时,不管是官方文档还是身边有经验的同事,总会拿ClassComponent
的生命周期来类比Hooks API
的执行时机。
这固然是很好的上手方式,但是当我们熟练运用Hooks
时,就会发现,这两者的概念有很多割裂感,并不是同一抽象层次可以互相替代的概念。
比如:替代componentWillReceiveProps
的Hooks
是什么呢?
可能有些同学会回答,是useEffect
:
useEffect( () => {
console.log('something updated');
}, [props.something])
但是componentWillReceiveProps
是在render阶段
执行,而useEffect
是在commit阶段
完成渲染后异步执行。
这篇文章可以帮你更好理解
componentWillReceiveProps
:深入源码剖析componentWillXXX为什么UNSAFE
所以,从源码运行规律的角度看待Hooks
,可能是更好的角度。这也是为什么上文说Hooks
是React
世界的电子
而不是原子
的原因。
<!-- ## Hooks设计动机 那么真的有`Hooks`能做而`ClassComponent`无法实现的`feature`么? 是的。 让我们再来看看`React`耗时三年重构完成的`Fiber结构`。在之前的章节我们讲过,这次重构的一大目的是**使更新可以异步执行并且可中断**。 现在让我们看看另一大目的:**使同一组件在同一时间可以拥有多个状态,即同一个组件可以拥有多条时间线**。 > [React Core Team Sebastian谈Hooks设计动机](https://twitter.com/sebmarkbage/status/1084539728743956481) `fiber`可以直译为`光纤`。 可以看到,一束`光纤`内部存在多束同时工作的玻璃芯。在`React`中,每条玻璃芯代表一个`Component`的时间线。 由于`ClassComponent`遵循`OOP`原则,`逻辑`和`状态`耦合在`实例`内部,无法在同一时间拥有多个`状态`(即同一时间只存在一个`this.state`)。 对于`Hooks`来说,`FunctionComponent`契合`FP`的编程思想(即`无状态`),更新组件时`Hooks`的`状态`保存在`闭包`中。换言之,同一`FunctionComponent`在同一时间可以拥有保存在不同`闭包`中的多个`状态`。 ::: details 多条时间线 Demo 你可以使用[useDeferredValue](https://zh-hans.reactjs.org/docs/concurrent-mode-reference.html#usedeferredvalue)使同一组件的某个`状态`在同一时间拥有多条时间线。 不同时间线重合的时间视**用户设备的性能**不同而不同。 在Demo中,你可以从控制台看到不同`状态`的`值`与`更新时间` [Demo](https://codesandbox.io/s/friendly-bush-hk5co) ::: -->
总结
Concurrent Mode
是React
未来的发展方向,而Hooks
是能够最大限度发挥Concurrent Mode
潜力的Component
构建方式。
正如Dan在React Conf 2018
演讲结尾所说:你可以从React
的LOGO
中看到这些围绕着核心
的电子飞行轨道
,Hooks
可能一直就在其中。