简介
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
定义:
Hook 是一些可以让你在函数组件里“钩入” React state 及生命周期等特性的函数。
请记住Hook是:
- 完全可选的
- 100% 向后兼容的
Hook 不会影响你对 React 概念的理解
为什么要在React中引入Hook?
原因一:在组件之间复用状态逻辑很难
原有解决方案:render props、高阶组件、providers、consumers
缺点:
- 嵌套地狱
- 需要改变组件结构
这说明了一个更深层次的问题:React 需要为共享状态逻辑提供更好的原生途径。
原因二:复杂组件变得难以理解
- 我们经常维护一些组件,组件起初很简单,但是逐渐会被状态逻辑和副作用充斥。
- 每个生命周期常常包含一些不相关的逻辑。
组件常常在 componentDidMount 和 componentDidUpdate 中获取数据。但是,同一个 componentDidMount 中可能也包含很多其它的逻辑,如设置事件监听,而之后需在 componentWillUnmount 中清除。相互关联且需要对照修改的代码被进行了拆分,而完全不相关的代码却在同一个方法中组合在一起。如此很容易产生 bug,并且导致逻辑不一致。
原因三:难以理解的class组件
- 理解 JavaScript 中 this 的工作方式
- 还不能忘记绑定事件处理器
- 需区分class组件与函数组件的使用场景
- class 不能很好的压缩,并且会使热重载出现不稳定的情况
Class 在作为 React 组件的载体时,是否真的合适呢?
- React 组件之间是不会互相继承的。
- 因为所有 UI 都是由状态驱动的,因此很少会在外部去调用一个类实例(即组件)的方法。要知道,组件的所有方法都是在内部调用,或者作为生命周期方法被自动调用的。
原因四:Hook出现前,函数式组件的局限:
函数组件无法存在内部状态,必须是纯函数,而且也无法提供完整的生命周期机制。这就极大限制了函数组件的大规模使用。
使用Hook的好处
好处一:简化逻辑复用
- 从组件中提取状态逻辑,使得这些逻辑可以单独测试并复用。
- 在无需修改组件结构的情况下复用状态逻辑。
好处二:有助于关注分离
- Class组件:代码从技术角度组织在一起
在
componentDidMount
中完成订阅,在componentWillUnmount
中完成取消订阅 - 函数组件 + Hook:代码从业务角度组织在一起
在一个
useEffect
中可以完成订阅与取消订阅的编码