React 常用 Hooks 解析
在 React 中,Hooks 是让函数组件拥有状态和其他 React 特性的关键工具。以下是几个最常用、最重要的内置 Hook 的详细解释:
1. useState:管理组件的状态
useState 是最基础的 Hook,用于在函数组件中添加本地状态(state)。
基本用法:
const [state, setState] = useState(initialValue);state:当前状态值。setState:更新状态的函数。initialValue:初始状态(惰性初始化也支持函数形式)。示例:
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<>
<p>点击次数: {count}</p>
<button onClick={() => setCount(count + 1)}>
增加
</button>
</>
);
}特点:
状态是“快照”:每次渲染时获取的是固定值。
更新函数可以接收函数形式以访问前一个状态:
setCount(prev => prev + 1)。每次调用
setState都会触发重新渲染(除非新旧值相等且为原始类型)。
✅ 适用场景:表单输入、开关控制、计数器等需要记忆数据的交互。
2. useEffect:处理副作用(Side Effects)
useEffect 用于在组件渲染后执行一些与外部系统同步的操作,比如数据获取、订阅、手动修改 DOM 等。
基本语法:
useEffect(() => {
// 副作用逻辑
return () => {
// 清理逻辑(可选)
};
}, [dependencies]); // 依赖数组示例:连接/断开聊天室
import { useEffect } from 'react';
function ChatRoom({ roomId }) {
useEffect(() => {
const connection = createConnection(roomId);
connection.connect();
return () => {
connection.disconnect();
};
}, [roomId]); // 当 roomId 变化时重新连接
}三种常见模式:
模式 | 写法 | 用途 |
|---|---|---|
每次渲染后运行 |
| 很少使用,容易造成死循环 |
仅首次挂载时运行 |
| 初始化、日志埋点、一次性订阅 |
依赖某些值变化时运行 |
| 同步 prop/state 到外部系统 |
注意事项:
不要滥用 Effect:如果只是根据 state 计算另一个 state,应使用
useMemo或直接在渲染中计算。清理机制很重要:避免内存泄漏,如取消订阅、清除定时器。
开发环境下
useEffect默认运行两次(仅限严格模式),帮助发现遗漏的清理逻辑。
✅ 适用场景:API 请求、事件监听、动画启动/销毁、第三方库集成。
3. useContext:跨层级传递数据
useContext 允许你订阅 React 的 Context,从而避免层层传递 props(俗称“prop drilling”)。
使用步骤:
创建 Context:
import { createContext, useContext } from 'react'; const ThemeContext = createContext('light');在父组件中提供值:
<ThemeContext.Provider value="dark"> <Toolbar /> </ThemeContext.Provider>子组件中读取上下文:
function Toolbar() { const theme = useContext(ThemeContext); return <div>当前主题: {theme}</div>; }
示例完整代码:
import { createContext, useContext } from 'react';
const ThemeContext = createContext();
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button style={{ background: theme === 'dark' ? '#333' : '#fff' }}>按钮</button>;
}✅ 适用场景:主题切换、用户登录信息、语言国际化、全局配置等需要深层传递的数据。
4. useReducer:管理复杂状态逻辑
useReducer 是 useState 的替代方案,适用于状态逻辑较复杂的情况,例如状态之间相互依赖,或下一个状态依赖于之前多个状态。它借鉴了 Redux 的设计思想,通过一个 reducer 函数来定义状态如何根据action进行更新。
基本用法:
const [state, dispatch] = useReducer(reducer, initialState);state:当前状态对象。dispatch:分发 action 的函数,触发状态更新。reducer:纯函数,接收(state, action)并返回新状态。initialState:初始状态。
示例:计数器增强版(支持增加、减少、重置)
import { useReducer } from 'react';
// 定义 reducer 函数
function counterReducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
case 'reset':
return { count: 0 };
default:
throw new Error(`未知 action: ${action.type}`);
}
}
function Counter() {
const [state, dispatch] = useReducer(counterReducer, { count: 0 });
return (
<>
<p>当前计数: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>+1</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-1</button>
<button onClick={() => dispatch({ type: 'reset' })}>重置</button>
</>
);
}优点:
将状态更新逻辑集中到 reducer 中,更易于测试和维护。
适合复杂状态转换,尤其是涉及多个子值的状态对象。
与
useContext结合可实现轻量级全局状态管理。
✅ 适用场景:表单处理(多字段)、购物车、游戏状态机、具有明确动作类型的复杂 UI 逻辑。
小结:四大核心 Hook 对比
Hook | 作用 | 典型用途 | 是否有依赖项 |
|---|---|---|---|
| 添加本地状态 | 表单、计数器、显示/隐藏 | ❌ |
| 执行副作用 | 数据请求、DOM 操作、订阅 | ✅ |
| 读取上下文 | 主题、用户信息、i18n | ❌ |
| 管理复杂状态逻辑 | 多字段表单、购物车、状态机 | ❌ |
这些 Hook 构成了 React 函数组件的核心能力。它们都必须遵守 Hook 规则:
只能在函数组件或自定义 Hook 的顶层调用。
不能在条件语句、循环中调用。
名称必须以
use开头(便于 lint 工具检查)。
掌握这四个 Hook,你就已经掌握了 React 开发的绝大多数场景!
参考资料
React 是一个用于构建用户界面的 JavaScript 库,特别擅长将页面拆分为可重用、可嵌套的组件。每个组件本质上是一个函数,可以包含标签和逻辑,并根据状态变化动态更新 UI。通过 useState 等 Hook,组件能够管理自身的数据状态,并在状态改变时自动触发重新渲染。React 采用声明式编程范式,使开发者能更直观地描述界面在不同状态下的呈现方式,同时利用虚拟 DOM 和批处理机制优化性能,确保高效更新。