← 返回目录

第 13 卷

第 13 / 28 卷日期:

状态数据结构支持任意数据类型(基本类状态是一个对象,所有状态字
型、对象、数组等),但推荐段都包含在该对象中,复杂状
将复杂状态拆分为多个独立态需嵌套在对象中(如
的 useState(如 count、state = { user: {
name 分别声明),便于管name: 'xxx', age: 18
理。} })。
生命周期关联无直接生命周期方法,通过拥有明确的生命周期方法
useEffect 模拟生命周期逻辑(componentDidMount、
(如componentDidUpdate、
componentDidMount:componentWillUnmount
useEffect(() => { ...等),状态更新逻辑可直接写
}, []);在对应生命周期中。

componentDidUpdate:

useEffect(() => { ...

}, [count]))。

状态更新后获取新状态更新函数是异步的,无法在调setState 是异步的,无法在调
用后立即获取新状态;需通过用后立即获取新状态;可通
更新函数的函数形式过 setState 的第二个参数
(setCount(prev => {(回调函数)获取新状态
... }))获取前一个状态,(this.setState({
或在 useEffect 中监听状态变count: 1 }, () =>
化获取新状态。console.log(this.state

.count))),或在 componentDidUpdate 中获

取。

性能优化方式通过 useMemo 缓存计算结通过 PureComponent 或重
果,useCallback 缓存函数引写
用,避免不必要的重新渲染;shouldComponentUpdate
复杂状态可使用 useReducer方法优化渲染;避免在
优化状态更新逻辑。render 中创建新对象/函数,

防止 props 引用变化导致的多余渲染。

this 指向问题无 this 指向问题,函数组件存在 this 指向问题,事件回
中无需关注 this,代码更简调中 this 可能为
洁。undefined,需通过 bind 绑

定或箭头函数规避(如 this.handleClick =

二十五、自定义 Hook 是什么,如何创建一个自定义 Hook?

  1. 什么是自定义 Hook?

自定义 Hook 是“基于 React 内置 Hooks 封装的、可复用的函数”,命名以 use 开头(如 useUser、useRequest),用于抽取多个组件共有的逻辑(如状态管理、副作用处理、数据请求

等),让函数组件能够轻松复用这些逻辑,同时避免类组件中 HOC 或 Render Props 导致的嵌套问题。

核心特点:

• 命名必须以 use 开头,这是 React 识别 Hook 的约定,确保 ESLint 等工具能够检测 Hook 的使

用规范;

• 内部可调用 React 内置 Hooks(如 useState、useEffect、useContext 等),但需遵循 Hook 的

使用规则(如只能在顶层调用);

  • 可接收参数,根据参数动态调整逻辑(如请求 Hook 可接收请求地址、请求参数);
  • 可返回任意数据(状态、函数、对象等),供调用的组件使用;
  • 没有组件结构,仅封装逻辑,调用时与普通函数一样,无需嵌套组件,代码简洁。

核心价值:实现逻辑复用,减少代码冗余,提升组件的简洁性和可维护性。

  1. 如何创建一个自定义 Hook?

创建自定义 Hook 的核心步骤是“抽取复用逻辑 → 用函数封装 → 内部调用内置 Hooks → 返回组件所需数据/函数”,具体步骤及示例如下:

(1)创建步骤

  1. 识别复用逻辑:分析多个组件中重复的逻辑(如数据请求、状态管理、副作用处理),确定需要抽

取的代码块;

  1. 定义 Hook 函数:创建一个以 use 开头的函数,作为自定义 Hook 的载体;
  2. 封装逻辑与内置 Hooks:在函数内部调用 React 内置 Hooks(如 useState 管理状态、useEffect

处理副作用),实现复用逻辑;

  1. 设计参数(可选):根据逻辑的灵活性需求,为 Hook 设计参数(如请求地址、配置项),让

Hook 适配不同场景;

  1. 返回组件所需数据:将组件需要的状态、操作函数等作为返回值(可返回单个值、数组、对象),

供组件使用;

Hook。

Code block

1 2// 1. 定义自定义 Hook:useRequest.js

3import { useState, useEffect } from 'react';

4 5// 接收请求函数和依赖数组作为参数

6function useRequest(requestFn, dependencies = []) {
7// 2.用内置Hooks管理状态
8const [data, setData] = useState(null);//存储请求结果
9const [loading, setLoading] = useState(false);//加载状态
10const [error, setError] = useState(null);//错误状态

11

12// 3.用useEffect处理副作用(发送请求)
13const fetchData = async () => {
14setLoading(true);
15setError(null);//重置错误状态
16try {
17const result = await requestFn();//执行传入的请求函数
18setData(result);
19} catch (err) {
20setError(err.message);
21} finally {
22setLoading(false);//无论成功失败,结束加载
23}
24};

25

26//组件挂载时执行一次,依赖变化时重新执行
27useEffect(() => {
28fetchData();
29}, dependencies);

30 31// 4. 返回组件所需的数据和函数

32return { data, loading, error, refetch: fetchData };

33} 34

35export default useRequest;

使用自定义 Hook 的组件:

全站分卷索引 · 28 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷
  9. 9第 9 卷
  10. 10第 10 卷
  11. 11第 11 卷
  12. 12第 12 卷
  13. 13第 13 卷
  14. 14第 14 卷
  15. 15第 15 卷
  16. 16第 16 卷
  17. 17第 17 卷
  18. 18第 18 卷
  19. 19第 19 卷
  20. 20第 20 卷
  21. 21第 21 卷
  22. 22第 22 卷
  23. 23第 23 卷
  24. 24第 24 卷
  25. 25第 25 卷
  26. 26第 26 卷
  27. 27第 27 卷
  28. 28第 28 卷