你不知道的React系列(十二)React Hooks

110 阅读2分钟

「回顾 2022,展望 2023,我正在参与2022 年终总结征文大赛活动

动机

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

  • React 没有提供将可复用性行为“附加”到组件的途径(例如,把组件连接到 store)

  • render props高阶组件需要重新组织你的组件结构,这可能会很麻烦,使你的代码难以理解

  • providers,consumers,高阶组件,render props 等其他抽象层组成的组件会形成“嵌套地狱”

  • 使用 Hook 从组件中提取状态逻辑,使得这些逻辑可以单独测试并复用

  • Hook 使你在无需修改组件结构的情况下复用状态逻辑

复杂组件变得难以理解

  • 状态逻辑和副作用复杂混乱

  • 每个生命周期常常包含一些不相关的逻辑

    componentDidMountcomponentDidUpdate 中获取数据

  • 不可能将组件拆分为更小的粒度测试带来了一定挑战

  • 状态管理库引入了很多抽象概念,需要你在不同的文件之间来回切换,复用变得困难

  • Hook 将组件中相互关联的部分拆分成更小的函数(比如设置订阅或请求数据),而并非强制按照生命周期划分

  • 使用 reducer 来管理组件的内部状态

难以理解的 class

JavaScript 中 this 的工作方式

  • 不能忘记绑定事件处理器

  • 没有稳定的语法提案

  • 这些代码非常冗余

  • class 不能很好的压缩

  • 热重载出现不稳定的情况

Hook 使用规则

  • 只能在函数最外层调用 Hook。不要在循环、条件判断或者子函数中调用

  • 只能在 React 的函数组件和 hook 函数中调用 Hook

  • 不要在其他 JavaScript 函数中调用

自定义 Hook

目的

  • 自定义 hook 可以把组件逻辑封装成函数

  • 减少组件数量render props and higher-order components

  • 清楚表达你代码的逻辑

  • 数据流向更加清楚

  • 方便升级相关代码使用新的 API

  • 容易重构相关代码

操作

  • 抽离组件逻辑,并且遵守 hook 规则

  • 自定义 Hook 必须以 “use” 开头

    命名规则尽可能描述具体功能或者系统不要使用生命周期相关名称

注意

  • hook 共享 state 的逻辑而不是 state 本身

  • hook 之间可以传递 reactive values 和函数(使用useEffectEvent处理)

什么时候使用

开始编写 Effect 时候考虑把相关逻辑放在自定义 Hook 里面