前端开发
编写或审查 React useEffect…
在编写或审查 React 组件中的 useEffect、派生状态、数据获取或状态同步时,判断何时需要 Effect 以及更好的替代方案。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
编写或审查 React useEffec通用
解决思路
- 若要从 props/state 派生状态,不要使用 `useState` + `useEffect`;改为在渲染期间直接计算。
- 若计算开销昂贵,不要用 `useEffect` 来缓存结果;改用 `useMemo`。
- 若要在 prop 变化时重置 state,不要用 `useEffect` 调用 `setState`;改为在组件上使用 `key` prop。
- 若要响应用户事件,不要用 `useEffect` 监听 state;改为直接在事件处理器中处理。
- 若要通知父组件状态变化,不要在 `useEffect` 中调用 `onChange`;改为在事件处理器中调用。
- 若要获取数据,不要使用没有 cleanup 的 `useEffect`;改为使用带 cleanup 的 `useEffect`,或使用框架内置的数据获取机制。
- 需要与外部系统同步时(如非 React widget、浏览器 API),使用 Effect。
- 需要订阅外部 store 时,使用 Effect;尽可能改用 `useSyncExternalStore`。
- 需要在组件显示时运行 analytics/logging 时,使用 Effect。
- 需要进行数据获取时,使用带正确 cleanup 的 Effect,或使用框架内置机制。
- 转换数据以供渲染时,不要用 Effect;改为在组件顶层计算,React 会自动重新运行计算。
- 处理用户事件时,不要用 Effect;改为使用事件处理器,因为你明确知道发生了什么。
- 派生状态时,不要用 Effect;直接计算,例如 `const fullName = firstName + ' ' + lastName`。
- 链式更新状态时,不要用 Effect;改为在事件处理器中一次性计算所有下一状态。
- 决策树:如果需要响应点击、提交、拖拽等用户交互,使用事件处理器。
- 决策树:如果组件出现在屏幕上,使用 Effect 进行外部同步或 analytics。
- 决策树:如果 props/state 变化后需要派生值,在渲染期间计算;如果计算昂贵,使用 `useMemo`。
- 决策树:如果 prop 变化时需要重置 state,在组件上使用 `key` prop。
- 查阅 `./anti-patterns.md`,了解常见错误及其修复方式。
- 查阅 `./alternatives.md`,了解 `useMemo`、`key` prop、状态提升、`useSyncExternalStore` 等替代方案。
适用边界 · 注意事项
- 当没有任何外部系统需要同步时,不应使用 Effect。
- 不要用 Effect 处理用户交互、派生状态、链式状态更新或 prop 变化重置 state;这些都有更简单的替代方案。
- 如果框架已提供内置数据获取机制,不要手写无 cleanup 的 `useEffect` 来获取数据。