Skip to content

React Hooks 详解

日常使用的 React hooks,按用途分组:保存状态、执行 effect、缓存计算、共享 context,以及接触渲染之外的世界。每行将 hook 与它的用途配对。

hook 是一个函数,让函数组件接入 React 的能力:状态、生命周期、context 和性能调优。两条规则:在顶层调用 hooks(绝不在循环或条件中调用),并且只在 React 函数中调用。剩下的就是为任务选对 hook。

参考表格 · 24 条目
24 of 24 rows
状态
保存一个值,该值变化时会触发重新渲染。组件本地状态:表单字段、开关、计数器。
保存由 action reducer 驱动的状态,就像一个小型 store。包含多个相关字段或复杂转换的状态。
保存一个可变值,变化时不会触发重新渲染。可变容器、定时器,以及通过 .current 直接访问 DOM。
副作用
在渲染后运行副作用,可选返回清理函数。获取数据、订阅,以及与外部系统同步。
effect 返回的函数会在下一个 effect 之前以及卸载时再次运行。清理订阅和定时器,或中止进行中的 fetch。
与 useEffect 类似,但在 DOM 变更后同步触发。在浏览器绘制前读取或写入布局(toast、tooltip)。
事件处理器响应用户操作而运行;effect 在渲染后运行以完成同步。用户触发的逻辑放在处理器里,渲染触发的逻辑放在 effect 里。
在开发环境下将组件挂载两次,让 effect 运行、清理、再运行。在上生产之前发现重复订阅和缺失的清理。
性能
缓存计算值,直到其依赖变化。避免跨渲染的昂贵重复计算;有意改变依赖中的某个值即可让缓存失效。
缓存函数引用,直到其依赖变化。传给 memo 化子组件或用作依赖项的稳定回调。
跳过 props 未变化的组件的重新渲染。重量级子组件;浅比较不够时传入比较函数作为第二个参数(它是 HOC,不是 hook)。
Context 与外部句柄
读取 context 值,无需逐层传递 props。在整个树中共享的主题、语言环境或已登录用户。
自定义父组件通过 ref 看到的实例。通过 forwardRef 从子组件暴露一个收窄的 API。
并发与其他
将状态更新标记为非紧急,让界面保持响应。在重量级列表重新渲染时保持输入流畅。
推迟一个值,使更新可以被中断。不用定时器就实现昂贵渲染的防抖。
为无障碍属性生成稳定且唯一的 id。在服务端和客户端渲染之间关联 label 与 input。
在渲染期间读取 promise 或 context;是唯一可以有条件调用的 hook。配合 Suspense 解包 promise,或在提前返回中读取 context。
保存由表单 action 驱动的状态,并附带 pending 标志。内联展示错误或更新状态的表单提交。
立即渲染乐观值,action 结算后回落到真实状态。在服务器请求进行中时显示点赞或已发送的消息。
读取外层 <form> 的 pending 状态,无需 props。在父表单提交时自行禁用的提交按钮。
订阅 React 之外的 store 并读取一致的快照。在线状态等浏览器 API,或第三方状态 store。
在 layout effect 之前运行,为注入 CSS-in-JS 规则而生。必须在读取布局前插入规则的样式库。
在 React DevTools 中为 hook 的内部状态显示自定义标签。调试时标注自定义 hook 保存的内容。
你自己编写的 hook,组合内置 hooks 来共享逻辑。可复用的有状态行为,如 useFetch 或 useMediaQuery。