type
status
date
slug
summary
tags
category
icon
password

Hook

Hook概述

Hook可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

什么是 Hook?

Hook 是一个特殊的函数,可以让你在函数组件里“钩入” React state生命周期 等特性的函数。
Hook 不能在 class 组件中使用 —— 这使得你不使用 class 也能使用 React。React 内置了一些像 useState 这样的 Hook。你也可以创建你自己的 Hook 来复用不同组件之间的状态逻辑。我们会先介绍这些内置的 Hook。

useState(状态钩子)

模式:
上面的三个值均可自定义名称,分别是:
  • state取值变量名
  • state设值方法名
  • 初始值
    • 初始值可以是数字、字符串、对象、数组等
例子:

声明多个 state 变量

Effect Hook (副作用钩子)

你之前可能已经在 React 组件中执行过数据获取、订阅 或者手动修改 DOM。我们统一把这些操作称为“副作用”,或者简称为“作用”。

useEffect(生命周期钩子)

useEffect 就是一个 Effect Hook,给函数组件增加了操作副作用的能力。它跟 class 组件中的 componentDidMountcomponentDidUpdatecomponentWillUnmount 具有相同的用途,只不过被合并成了一个 API。(我们会在使用 Effect Hook (opens new window)里展示对比 useEffect 和这些方法的例子。)
例如,下面这个组件在 React 更新 DOM 后会设置一个页面标题:
当你调用 useEffect 时,就是在告诉 React 在完成对 DOM 的更改后运行你的“副作用”函数。由于副作用函数是在组件内声明的,所以它们可以访问到组件的 props 和 state。默认情况下,React 会在每次渲染后调用副作用函数 —— 包括第一次渲染的时候。

“清除”副作用

副作用函数还可以通过返回一个函数来指定如何“清除”副作用。例如,在下面的组件中使用副作用函数来订阅好友的在线状态,并通过取消订阅来进行清除操作:
在这个示例中,React 会在组件销毁时取消对 ChatAPI 的订阅,然后在后续渲染时重新执行副作用函数。(如果传给 ChatAPIprops.friend.id 没有变化,你也可以告诉 React 跳过重新订阅 (opens new window)。)
useState 一样,你可以在组件中多次使用 useEffect
通过使用 Hook,你可以把组件内相关的副作用组织在一起(例如创建订阅及取消订阅),而不要把它们拆分到不同的生命周期函数里。
详细说明
你可以在这一章节了解更多关于 useEffect 的内容:使用 Effect Hook(opens new window)

Hook 使用规则

Hook 就是 JavaScript 函数,但是使用它们会有两个额外的规则:
  • 只能在函数最外层调用 Hook。不要在循环、条件判断或者子函数中调用。
  • 只能在 React 的函数组件中调用 Hook。不要在其他 JavaScript 函数中调用。(还有一个地方可以调用 Hook —— 就是自定义的 Hook 中,我们稍后会学习到。)
同时,我们提供了 linter 插件 (opens new window)来自动执行这些规则。这些规则乍看起来会有一些限制和令人困惑,但是要让 Hook 正常工作,它们至关重要。
详细说明
你可以在这章节了解更多关于这些规则的内容:Hook 使用规则 (opens new window)

自定义 Hook (Hook的使用逻辑封装)

有时候我们会想要在组件之间重用一些状态逻辑。目前为止,有两种主流方案来解决这个问题:高阶组件 (opens new window)render props (opens new window)。自定义 Hook 可以让你在不增加组件的情况下达到同样的目的。
前面,我们介绍了一个叫 FriendStatus 的组件,它通过调用 useStateuseEffect 的 Hook 来订阅一个好友的在线状态。假设我们想在另一个组件里重用这个订阅逻辑。
首先,我们把这个逻辑抽取到一个叫做 useFriendStatus 的自定义 Hook 里:
它将 friendID 作为参数,并返回该好友是否在线:
现在我们可以在两个组件中使用它:
每个组件间的 state 是完全独立的。Hook 是一种复用*状态逻辑*的方式,它不复用 state 本身。事实上 Hook 的每次调用都有一个完全独立的 state —— 因此你可以在单个组件中多次调用同一个自定义 Hook。
自定义 Hook 更像是一种约定而不是功能。如果函数的名字以 “use” 开头并调用其他 Hook,我们就说这是一个自定义 HookuseSomething 的命名约定可以让我们的 linter 插件在使用 Hook 的代码中找到 bug。
你可以创建涵盖各种场景的自定义 Hook,如表单处理、动画、订阅声明、计时器,甚至可能还有更多我们没想到的场景。我们很期待看到 React 社区会出现什么样的自定义 Hook。
详细说明
我们会在这一章节介绍更多关于自定义 Hook 的内容: 创建你自己的 Hook (opens new window)

其他 Hook

除此之外,还有一些使用频率较低的但是很有用的 Hook。比如,useContext (opens new window)让你不使用组件嵌套就可以订阅 React 的 Context。
另外 useReducer (opens new window)可以让你通过 reducer 来管理组件本地的复杂 state。
详细说明
你可以在这一章节了解更多关于所有内置 Hook 的内容:Hook API 索引 (opens new window)
React笔记-案例演示React笔记-高级指引
Loading...
慕雨
慕雨
一个普通的干饭人🍚
公告
🎉欢迎来到慕雨的博客小站🎉
这里是我的个人学习、生活记录
--- 免责声明 ---
⚠️ 本站内容仅代表个人观点
⚠️ 本站内容仅供学习参考使用