# 1. React Hooks
Hook 是一些可以让你在函数组件里“钩入” React state 及生命周期等特性的函数。Hook 不能在 class 组件中使用
# 1.1. Hook 使用规则
- 只能在函数最外层调用 Hook。不可在循环、条件判断或者子函数中调用。
- 只能在 React 的函数组件或自定义的 Hook 中调用 Hook。不要在其他 JavaScript 函数中调用。
可以使用eslint-plugin-react-hooks
来检测,在 Webpack 中添加配置如下:
"eslintConfig": {
"extends": "react-app",
"plugins": [
"react-hooks"
],
"rules": {
"react-hooks/rules-of-hooks":"error"
}
},
# 1.2. Hook 如何把调用和组件联系起来的?
React 保持对当先渲染中的组件的追踪。多亏了 Hook 规范,我们得知 Hook 只会在 React 组件中被调用(或自定义 Hook —— 同样只会在 React 组件中被调用)。
每个组件内部都有一个「记忆单元格」列表。它们只不过是我们用来存储一些数据的 JavaScript 对象。当你用 useState() 调用一个 Hook 的时候,它会读取当前的单元格(或在首次渲染时将其初始化),然后把指针移动到下一个。这就是多个 useState() 调用会得到各自独立的本地 state 的原因。
# 1.3. 类组件的不足
- 状态逻辑难以复用
- 缺少复用机制
- 不方便封装逻辑,使用渲染属性和高阶组件也有缺点
- 渲染属性和高阶组件导致层级冗余
- 无论是高阶组件还是渲染属性,都相当与在原来的组件之上增加了新的组件层次。尤其是在 Chrome 调试器上会看到为了服用逻辑而添加的狠多组件层级,显得十分臃肿。不仅是调试体验问题、也存在着运行性能的问题
- 缺少复用机制
- 趋向复杂时难以维护
- 生命周期函数函数混杂不相干逻辑
- 相关逻辑代码经常会打散到不同生命周期中
- this 指向困扰
- 内联函数需要绑定 this, 否则每次渲染都创建一个箭头函数
- 类成员函数不能保证 this
# 1.4. hooks 优势
- 函数组件无类实例 this 问题
- hooks 是函数组件环境,所有逻辑都在函数内部,没有实例化概念,无复杂的 this 问题
- 自定义 Hook 函数方便复用状态逻辑
- hooks 指的是在函数内部调用的特殊函数,我们可以自定义 hooks 函数,在 hooks 函数内部,依旧可以调用 useState 和 useEffect 等 hooks 函数。这样就可以非常高效的将可复用逻辑提取出来
- 副作用的关注点分离
- hooks 天生优化了副作用代码逻辑
- 每个 useEffect 来实现一个逻辑,不同逻辑写在不同的 useEffect 中,比冗在同一生命周期中好很多
- 以前副作用大都是写在生命函数周期中
- 副作用:
- 发送网络请求
- 访问原始 DOM 元素
- 访问本地存储
- 绑定解绑事件
- hooks 天生优化了副作用代码逻辑