前言
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
一、Hook是什么
Hook 是一些可以让你在函数组件里“钩入” React state 及生命周期等特性的函数。
二、Hook的作用
1、可以使用 Hook 从组件中提取状态逻辑,使得这些逻辑可以单独测试并复用。Hook 使你在无需修改组件结构的情况下复用状态逻辑。 这使得在组件间或社区内共享 Hook 变得更便捷。
2、Hook 将组件中相互关联的部分拆分成更小的函数(比如设置订阅或请求数据),而并非强制按照生命周期划分。你还可以使用 reducer 来管理组件的内部状态,使其更加可预测。 例如,可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。
3、Hook 使你在非 class 的情况下可以使用更多的 React 特性。 从概念上讲,React 组件一直更像是函数。而 Hook 则拥抱了函数,同时也没有牺牲 React 的精神原则。Hook 提供了问题的解决方案,无需学习复杂的函数式或响应式编程技术。
三、如何使用Hook
1、官方Hook——State Hook
import React, { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
第一行: 引入 React 中的 useState Hook。它让我们在函数组件中存储内部 state。
第四行: 在 Example组件内部,我们通过调用 useState Hook声明了一个新的state变量。它返回一对值给到我们命名的变量上。我们把变量命名为count,因为它存储的是点击次数。我们通过传0作为useState唯一的参数来将其初始化为0。第二个返回的值本身就是一个函数。它让我们可以更新count的值,所以我们叫它setCount。
第九行: 当用户点击按钮后,我们传递一个新的值给setCount。React会重新渲染Example组件,并把最新的count 传给它。
2、官方Hook——Effect Hook
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
// Update the document title using the browser API
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
四、使用Hook的规则
1、只在最顶层使用 Hook 不要在循环,条件或嵌套函数中调用 Hook, 确保总是在你的 React 函数的最顶层调用他们。遵守这条规则,你就能确保 Hook 在每一次渲染中都按照同样的顺序被调用。这让 React 能够在多次的 useState 和 useEffect 调用之间保持 hook 状态的正确。
2、只在 React 函数中调用 Hook 不要在普通的 JavaScript 函数中调用 Hook。你可以: ✅ 在 React 的函数组件中调用 Hook ✅ 在自定义 Hook 中调用其他 Hook 遵循此规则,确保组件的状态逻辑在代码中清晰可见。
五、自定义 Hook
通过自定义 Hook,可以将组件逻辑提取到可重用的函数中。例如一个验证用户权限的自定义Hook
import React, { useState, useEffect } from 'react';
function useUserStatus(userID) {
const [isAuth, setIsAuth] = useState(null);
useEffect(() => {
const auth = somecodeHandelAuth(userID);
setIsAuth(auth);
});
return isAuth;
}
使用时
const isAuth = useUserStatus(user.id);
自定义 Hook 必须以 “use” 开头吗?
必须如此。这个约定非常重要。不遵循的话,由于无法判断某个函数是否包含对其内部 Hook 的调用,React 将无法自动检查你的 Hook 是否违反了 Hook 的规则。
在两个组件中使用相同的 Hook 会共享 state 吗?
不会。自定义 Hook 是一种重用状态逻辑的机制(例如设置为订阅并存储当前值),所以每次使用自定义 Hook 时,其中的所有 state 和副作用都是完全隔离的。
自定义 Hook 如何获取独立的 state?
每次调用 Hook,它都会获取独立的 state。由于我们直接调用了 useUserStatus,从 React 的角度来看,我们的组件只是调用了 useState 和 useEffect。 正如我们在之前章节中了解到的一样,我们可以在一个组件中多次调用 useState 和 useEffect,它们是完全独立的。