React Hooks 是 React 16.8 引入的重要特性,让函数组件能够拥有类组件的状态和生命周期能力。以下是 React 官方提供的所有内置 Hooks,按功能分类整理,附带核心用法和场景说明:
一、基础 Hooks(最常用)
-
useState
-
功能:为函数组件添加状态管理。
const [count, setCount] = useState(0); // 初始值为0
// 更新状态(直接赋值或函数式更新)
setCount(prev => prev + 1); -
场景:管理组件内部的简单状态(如表单输入、开关状态等)。
useEffect
-
功能:处理组件的副作用(如数据请求、订阅、DOM 操作),替代类组件的生命周期。
-
用法:
// 组件挂载和更新时执行(依赖项变化才触发)
useEffect(() => {
const timer = setInterval(() => setCount(c => c + 1), 1000);
// 清理函数(组件卸载或依赖变化前执行)
return () => clearInterval(timer);
}, []); // 空依赖:只在挂载和卸载时执行 -
场景:数据加载、事件监听、定时器等需要 "副作用" 的操作。
useContext
-
功能:跨组件共享数据,避免 "props drilling"(层层传递 props)。
-
用法
// 先创建 Context
const ThemeContext = createContext('light');
// 在组件中获取 Context 值
const theme = useContext(ThemeContext);
场景:全局状态(如主题、用户信息)在多层组件中的共享
二、额外的 Hooks(处理复杂场景)
-
useReducer
-
功能:通过 reducer 管理复杂状态逻辑,类似 Redux 的简化版
// 定义 reducer 函数(状态更新规则)
function todoReducer(state, action) {
switch(action.type) {
case 'ADD': return [...state, action.payload];
default: return state;
}
}
// 在组件中使用
const [todos, dispatch] = useReducer(todoReducer, []);
// 触发更新
dispatch({ type: 'ADD', payload: '学习 Hooks' });
- 场景:状态逻辑复杂(多值关联、多操作类型)或需要通过子组件修改父组件状态。
2、useCallback
功能:缓存函数,避免因函数重新创建导致子组件不必要的重渲染
// 缓存 handleClick 函数,依赖项不变则函数引用不变
const handleClick = useCallback(() => {
console.log('点击了', count);
}, [count]); // 依赖 count,count 变则函数重新创建
3、useMemo
-
功能:缓存计算结果,避免每次渲染重复执行耗时计算。
// 缓存计算结果,依赖项不变则直接返回缓存值
const total = useMemo(() => {
return list.reduce((sum, item) => sum + item.price, 0);
}, [list]); // 依赖 list,list 变则重新计算 -
场景:复杂计算(如大数据列表过滤、排序)。
4、useRef
-
功能:创建一个可变的 ref 对象,可用于访问 DOM 元素或存储跨渲染周期的数据。
// 访问 DOM 元素
const inputRef = useRef(null);
useEffect(() => inputRef.current.focus(), []);// 存储跨渲染的数据(修改不会触发重渲染)
const timerRef = useRef(null);
timerRef.current = setInterval(...);
5、useImperativeHandle
-
功能 :自定义通过
ref
暴露给父组件的实例值,限制子组件暴露的接口。function ChildComponent(props, ref) {
const inputRef = useRef(null);
// 只暴露 focus 方法给父组件
useImperativeHandle(ref, () => ({
focus: () => inputRef.current.focus()
}));
return ;
}
// 父组件通过 ref 调用子组件暴露的方法
const childRef = useRef(null);
childRef.current.focus(); -
场景:父组件需要操作子组件 DOM,但希望限制访问范围(避免过度耦合)。
6、useLayoutEffect
-
功能 :与
useEffect
类似,但回调函数在 DOM 更新后同步执行 (而useEffect
是异步)。useLayoutEffect(() => {
// 读取 DOM 布局并立即修改(避免页面闪烁)
const { height } = elementRef.current.getBoundingClientRect();
elementRef.current.style.marginTop =${100 - height}px
;
}, []); -
场景:需要在 DOM 更新后立即读取布局信息并修改(如避免因样式计算导致的闪烁)。
7、useDebugValue
-
功能:在 React DevTools 中为自定义 Hook 显示标签,方便调试。
function useFriendStatus(friendId) {
const [isOnline, setIsOnline] = useState(null);
// 在 DevTools 中显示 "FriendStatus: 在线/离线"
useDebugValue(isOnline ? '在线' : '离线');
return isOnline;
} -
场景:开发自定义 Hook 时,提升调试体验。
三、React 18+ 新增 Hooks(并发特性相关)
-
useTransition
功能:标记非紧急更新,避免阻塞用户交互(如输入、点击)。const [isPending, startTransition] = useTransition();
// 紧急更新:立即响应输入
setInput(e.target.value);
// 非紧急更新:标记为过渡任务
startTransition(() => {
setFilteredList(filterData(e.target.value)); // 耗时操作
});
- 场景:输入搜索、列表筛选等需要 "优先响应输入,延迟处理结果" 的场景。
2、useDeferredValue
功能:为状态创建一个 "延迟版本",优先保证 UI 响应速度
const [input, setInput] = useState('');
// 延迟版本:input 更新后,deferredInput 会"滞后"更新
const deferredInput = useDeferredValue(input);
// 基于延迟值渲染(避免输入时卡顿)
return <List data={filter(deferredInput)} />;
- 场景 :与
useTransition
类似,简化非紧急状态的处理。
3、useId
功能:生成跨服务器和客户端的唯一 ID,用于表单关联、无障碍访问(ARIA)
const id = useId(); // 生成如 "r1:2" 的唯一ID
return (
<div>
<label htmlFor={`${id}-name`}>姓名</label>
<input id={`${id}-name`} />
</div>
);
- 场景:避免 SSR(服务器渲染)时客户端与服务器 ID 不匹配的问题。
4、useSyncExternalStore
-
功能:同步外部状态(如 Redux、localStorage),确保在并发渲染中状态一致性。
// 从外部 store 读取状态
const state = useSyncExternalStore(
store.subscribe, // 订阅状态变化
store.getState, // 获取当前状态
store.getServerState // 服务器初始状态(SSR用)
); -
场景 :集成外部状态管理库(如替代 Redux 的
useSelector
)。
5、useInsertionEffect
- 功能:在 CSS-in-JS 库中插入样式时使用,确保样式在 DOM 元素渲染前生效。
- 用法 :类似
useLayoutEffect
,但执行时机更早(在 DOM 突变前)。 - 场景:主要供 CSS-in-JS 库内部使用,普通开发很少直接用到。