React 学习之 Hooks

52 阅读3分钟

React Hooks 是 React 16.8 引入的一项革命性特性,它让函数组件也能拥有状态管理、生命周期和副作用处理等能力,彻底改变了 React 的开发方式。以 use 开头的函数,都是 React Hooks。它们更贴近原生 JavaScript 风格,逻辑复用更灵活,代码也更易读、易测试。


一、为什么需要 Hooks?

在 Hooks 出现之前,只有 class 组件能使用 state 和生命周期方法,而函数组件是“无状态”的。这导致:

  • 逻辑难以复用(如数据请求、订阅等)
  • 组件越来越臃肿(生命周期中混杂不相关的逻辑)
  • class 语法复杂(this 绑定、样板代码多)

Hooks 的出现,让函数组件也能“有状态”、“有生命周期”,并支持自定义逻辑抽象,真正实现了“关注点分离”。


二、常用内置 Hooks

1. useState —— 管理状态

jsx
编辑
const [count, setCount] = useState(0);
  • 作用:在函数组件中声明可变状态。

  • 特点

    • 初始值可以是任意类型(数字、对象、数组等)。

    • setState 可接收新值,也可接收函数(推荐用于依赖前一状态):

      jsx
      编辑
      setCount(prev => prev + 1);
      
    • ❗ 不能直接用于异步初始化(如 useState(fetchData()))。
      → 正确做法:在 useEffect 中请求数据后更新状态。

💡 提示:useState 只负责“存储”,不负责“获取”。


2. useEffect —— 处理副作用

jsx
编辑
useEffect(() => {
  // 副作用逻辑(如请求、订阅、DOM 操作)
  return () => {
    // 清理逻辑(如取消请求、清除定时器)
  };
}, [dependencies]);
  • 什么是副作用
    任何“纯函数之外”的操作,比如网络请求、手动修改 DOM、设置定时器等。
  • 三种典型用法(由第二个参数决定):
写法行为类比理解
useEffect(() => { ... }, [])仅在组件挂载时执行一次相当于 Vue 的 onMounted
useEffect(() => { ... }, [a, b])当 a 或 b 变化时重新执行类似 watch([a, b])
useEffect(() => { ... })每次渲染后都执行(慎用!)
  • 清理机制
    返回的函数会在 下一次 effect 执行前 或 组件卸载时 自动调用,用于释放资源(如 clearIntervalunsubscribe),相当于 Vue 的 onUnmounted

✅ 最佳实践:

  • 数据请求 → 放在 useEffect(..., [])
  • 定时器/监听器 → 一定要写 return 清理函数
  • 不要遗漏依赖项(可用 ESLint 插件自动检查)

三、自定义 Hooks —— 逻辑复用的利器

自定义 Hook 是一个use 开头的普通函数,内部可以调用其他 Hooks,用于提取和复用组件逻辑(注意:不是 UI 复用)。

示例:封装通用数据请求

jsx
编辑
// useFetch.js
function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    setLoading(true);
    fetch(url)
      .then(res => res.json())
      .then(setData)
      .finally(() => setLoading(false));
  }, [url]);

  return { data, loading };
}

// 在组件中使用
function UserList() {
  const { data, loading } = useFetch('/api/users');
  if (loading) return <div>加载中...</div>;
  return <ul>{data.map(user => <li key={user.id}>{user.name}</li>)}</ul>;
}

✅ 优势:

  • 逻辑与 UI 解耦
  • 多个组件可共享同一套状态管理逻辑
  • 单元测试更简单

四、Hooks 使用规则(必须遵守!)

  1. 只能在 React 函数组件或自定义 Hook 中调用
    (不能在普通函数、class 方法中使用)
  2. 不能在循环、条件语句或嵌套函数中调用
    → React 依赖 调用顺序的一致性 来正确关联每个 Hook 的状态

🔧 建议:安装 eslint-plugin-react-hooks,自动检测违规用法。


五、总结

Hook用途关键点
useState状态管理初始值、函数式更新
useEffect副作用处理依赖项、清理函数
自定义 Hook逻辑复用以 use 开头,组合内置 Hooks

Hooks 的核心思想
将组件视为“纯函数”(props → JSX),把副作用交给 useEffect;通过组合 Hooks,实现高内聚、低耦合的逻辑模块。

掌握 Hooks,就掌握了现代 React 开发的灵魂。它不仅简化了代码,更推动了前端工程化的进步——逻辑可复用、状态可预测、组件更纯粹