引入
我们之前会使用 useState, useMemo 或者各种各样的, 使用 use 开头的函数, 这些函数就叫做 React 的 Hooks.
当我们想要在两个函数之间共享逻辑的时候, 我们会把它提取到第三个函数中. 这个第三个函数就是我们的 Hooks 了.
另外, Hook 必须用 use 开头, 否则的话 React 无法检查 Hook 是否违反了 Hook 的规则.
自定义 Hooks
需要注意, Hooks 做的是将逻辑进行抽离, 不涉及 UI 部分. 例如下面这段代码, 模拟的进行了一个数据的请求.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import { useEffect, useState } from "react";
interface IUser { name: string; age: number; }
function App() { const [user, setUser] = useState<IUser>();
const fetchData = async () => { new Promise((resolve) => { setTimeout(() => { resolve({ name: "yyt", age: 18 }); }, 1000); }).then((res: IUser) => { const tmpUser: IUser = { name: res.name, age: res.age, }; setUser(tmpUser); }); };
useEffect(() => { fetchData(); }, []);
return ( <> <h1>User Info</h1> <h2>{user?.name}</h2> <h2>{user?.age}</h2> </> ); }
export default App;
|
可能这个请求的操作我们会多次用到, 那么就可以直接封装为一个 hook 了.
这里直接创建一个 hook, 叫做 useUserInfo.

随后, 就可以把所有的逻辑放在里面了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| import { useEffect, useState } from "react";
interface IUser { name: string; age: number; }
const useUserInfo = () => { const [user, setUser] = useState<IUser>({ name: "默认用户名", age: 0, });
const fetchData = async () => { new Promise((resolve) => { setTimeout(() => { resolve({ name: "yyt", age: 18 }); }, 1000); }).then((res: IUser) => { const tmpUser: IUser = { name: res.name, age: res.age, }; setUser(tmpUser); }); };
useEffect(() => { fetchData(); }, []);
return user; };
export default useUserInfo;
|
现在, 回到页面中, 就可以直接使用这个自定义钩子来实现目标效果了.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import useUserInfo from "./hooks/useUserInfo";
function App() { const user = useUserInfo();
return ( <> <h1>User Info</h1> <h2>{user?.name}</h2> <h2>{user?.age}</h2> </> ); }
export default App;
|
现在页面显示仍然正常, 并且保留了响应式. 这就是自定义 Hooks 了.
总结
自定义 Hooks, 其实就是一种特殊的写法, 允许将 React 的 hooks 函数抽象出来单独使用的一种方法. 本质上就是将一些代码抽象为函数, 不过这些代码中用到了 React 的钩子函数.
为了处理这种特殊的函数, 我们需要将这些函数写成一个 Hook, 方便后期的调用.