用途
React Effects Guidelines 是一份面向 React 开发者的编码指导规范,主题是何时应该使用 useEffect、何时应该避免使用它。文档以 React 官方文章《你可能不需要 Effect》(https://react.dev/learn/you-might-not-need-an-effect)作为主要参考,目的是减少不必要的 Effect,让组件逻辑更清晰、更易维护。
主要能力
文档提供了一套快速决策树。在添加 useEffect 之前,开发者应依次自问:
- 能否在渲染期间计算?→ 直接派生,不要存储后再同步。
- 是否只是在 prop 变化时重置状态?→ 改用 key 属性。
- 是否由用户事件触发?→ 放到事件处理器中。
- 是否在与外部系统同步?→ 此时 Effect 才是合适的。
文档还列出了 Effect 的合理用途:
- DOM 操作(聚焦、滚动、测量)
- 外部组件生命周期(终端、图表、非 React 库)
- 浏览器 API 订阅(ResizeObserver、IntersectionObserver)
- 挂载或 prop 变化时的数据获取
- 全局事件监听
使用方式
文档通过反模式与正确写法的代码对比来传达规范。
派生状态:不要用 state 存储再在 Effect 中同步,而应在渲染时直接计算。
// ❌ Derived state stored separately
const [fullName, setFullName] = useState('');
useEffect(() => setFullName(first + ' ' + last), [first, last]);
// ✅ Calculate during render
const fullName = first + ' ' + last;
事件逻辑:不要放在 Effect 中,而应放在事件处理器里。
// ❌ Event logic in effect
useEffect(() => { if (isOpen) doSomething(); }, [isOpen]);
// ✅ In the handler
const handleOpen = () => { setIsOpen(true); doSomething(); };
prop 变化时重置状态:不要用 Effect 重置,而应使用 key。
// ❌ Reset state on prop change
useEffect(() => { setComment(''); }, [userId]);
// ✅ Use key to reset
<Profile userId={userId} key={userId} />
订阅外部数据存储(非 DOM API)时,优先使用 useSyncExternalStore,而不是在 Effect 中手动订阅。
// ❌ Manual subscription in effect
const [isOnline, setIsOnline] = useState(true);
useEffect(() => {
const update = () => setIsOnline(navigator.onLine);
window.addEventListener('online', update);
window.addEventListener('offline', update);
return () => { /* cleanup */ };
}, []);
// ✅ Built-in hook for external stores
const isOnline = useSyncExternalStore(
subscribe,
() => navigator.onLine, // client
() => true // server
);
数据获取清理:始终用 ignore 标志处理竞态条件。
useEffect(() => {
let ignore = false;
fetchData(query).then(result => {
if (!ignore) setData(result);
});
return () => { ignore = true; };
}, [query]);
应用初始化:对于每次应用加载只执行一次(而非每次挂载一次)的逻辑,使用模块级守卫。
let didInit = false;
function App() {
useEffect(() => {
if (!didInit) {
didInit = true;
loadDataFromLocalStorage();
checkAuthToken();
}
}, []);
}
或者在模块初始化阶段(渲染前)执行:
if (typeof window !== 'undefined') {
checkAuthToken();
loadDataFromLocalStorage();
}
适用场景
该规范适用于所有使用 React 函数组件与 Hooks 的前端开发场景,尤其适合需要审查或重构 Effect 用法的团队,以及希望遵循 React 官方推荐实践的开发者。
限制
资料未提供该规范的版本、许可、安装方式、依赖要求或平台限制等信息,暂未提供。