React Hooks 详解
React Hooks 是 React 16.8 引入的功能,让我们在不编写 class 的情况下使用 state 以及其他的 React 特性。本页将涵盖所有主流 hooks 类型、作 用及代表性使用示例。
🎯 常见 React Hooks 一览
| Hook 名称 | 作用描述 |
|---|---|
useState | 添加本地状态 |
useEffect | 执行副作用(如数据请求、事件监听) |
useContext | 读取 React 上下文对象 |
useReducer | 类似 Redux 的状态管理 |
useRef | 引用 DOM 节点或保存可变变量 |
useMemo | 缓存计算结果 |
useCallback | 缓存函数引用 |
useLayoutEffect | 在 DOM 更新之前同步调用副作用 |
useImperativeHandle | 自定义暴露给父组件的 ref 操作 |
useId | 生成唯一 ID(用于表单、可访问性) |
useTransition | 并发特性中的低优先级更新 |
🔧 useState 示例
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
点击次数: {count}
</button>
);
}
📦 useEffect 示例
import { useEffect, useState } from 'react';
function UserList() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch('/api/users')
.then(res => res.json())
.then(setUsers);
}, []); // 空数组表示只在首次渲染后执行
return <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>;
}
📚 useContext 示例
const ThemeContext = React.createContext("light");
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button className={`btn-${theme}`}>按钮</button>;
}
🔁 useReducer 示例(类似 Redux)
const reducer = (state, action) => {
switch (action.type) {
case 'increment': return { count: state.count + 1 };
case 'decrement': return { count: state.count - 1 };
default: return state;
}
};
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
<span>{state.count}</span>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
</>
);
}
🔍 useRef 示例
function FocusInput() {
const inputRef = useRef(null);
return (
<>
<input ref={inputRef} />
<button onClick={() => inputRef.current.focus()}>聚焦</button>
</>
);
}
🧠 useMemo vs useCallback
- useMemo
- useCallback
const expensiveValue = useMemo(() => computeExpensiveValue(input), [input]);
用于缓存值(避免重复计算)。
const handleClick = useCallback(() => {
console.log("Clicked");
}, []);
用于缓存函数(防止子组件重复渲染)。
⚙️ useLayoutEffect vs useEffect
两者区别
useEffect异步执行,不会阻塞绘制;useLayoutEffect同步执行,在 DOM 变更后、绘制前调用。
useLayoutEffect(() => {
console.log('布局相关逻辑');
}, []);
🧩 useImperativeHandle 示例
const MyInput = forwardRef((props, ref) => {
const localRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => localRef.current.focus()
}));
return <input ref={localRef} />;
});
🔀 useTransition 示例
const [isPending, startTransition] = useTransition();
function handleChange(e) {
startTransition(() => {
setInput(e.target.value);
});
}
适用于输入优化、长列表切换等并发场景。
✅ 总结
- Hooks 是函数组件的核心;
- 常用的包括
useState、useEffect、useRef; useMemo和useCallback用于性能优化;useReducer提供类 Redux 的状态管理;- 高级 Hook 适用于复杂场景(如
useTransition、useImperativeHandle)