用途:本技能用于识别并修正 React 中 useEffect 的常见反模式,帮助判断某段逻辑究竟需不需要 Effect。核心判断是两个问题:是否在为渲染转换数据(是则改为渲染期计算);是否在处理用户事件(是则移入事件处理器)。两者都不符合时,才可能真的需要 Effect。
主要能力与替代方案:
- 由 props/state 派生值:不要用 Effect 加 setState,直接在渲染期计算;仅当计算确实昂贵(生产环境 profiling 稳定 ≥1ms)才用 useMemo。
- 重置组件状态:prop 变化时不要逐个 setState 重置,改用 key 让 React 视作不同组件实例。
- 调整部分状态:优先改为派生值(如存 id 派生选中对象),必要时才在渲染期调整状态。
- 用户事件逻辑:通知、导航、alert 等应放入事件处理器,而非监听状态变化的 Effect。
- POST 请求:由用户动作触发的提交应直接在事件处理器中发送;只有展示驱动的请求(如页面访问分析)才适合放 Effect。
- Effect 链:多个 Effect 互相 setState 会引发多次渲染,应合并到事件处理器并尽量派生。
- 应用初始化:用模块级 didInit 守卫或模块级代码,避免 StrictMode 下重复执行。
- 通知父组件:在同一事件处理器中同时更新子状态并调用 onChange,React 会批量处理;或改为完全受控组件。
- 向父传数据:应提升数据获取到父组件再向下传递,保持数据流向下。
- 订阅外部数据源:优先使用 useSyncExternalStore。
- 数据获取:这属于 Effect 的合理用途,但需用 ignore 标志或 abort controller 处理竞态并清理;生产环境建议用 TanStack Query / SWR 或自定义 hook。
用法与限制:技能以审查清单形式使用,检查必要性、清理、竞态、依赖项完整性、是否形成 Effect 链、是否只是伪装的 componentDidMount/componentDidUpdate。资料未提供安装命令或收费信息,也未说明具体平台要求。