| 状态 |
|---|
| 保存一个值,该值变化时会触发重新渲染。 | 组件本地状态:表单字段、开关、计数器。 |
| 保存由 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。 |