如何在 React 中正确使用 useEffect 来监听对象或数组依赖项的变化,避免无限循环或无效更新?
如何在 React 中正确使用 useEffect 来监听对象或数组依赖项的变化,避免无限循环或无效更新?
回答:
在 React 的 useEffect 中,若直接将对象或数组作为依赖项,由于每次渲染都会创建新的引用(即使内容相同),会导致 useEffect 误判依赖变化,从而可能引发无限循环或不必要的执行。正确的做法是:
- 避免不必要的引用变化:在父组件中使用 useMemo 或 useCallback 稳定依赖项的引用;
- 深度比较依赖项:若无法控制依赖项的引用,可借助自定义 hook(如 useDeepCompareEffect)进行深比较;
- 结构化解构或提取关键值:仅监听对象/数组中实际关心的原始值(如 id、count 等);
- 避免在 effect 内部更新依赖项状态:除非配合条件判断,防止 setState 触发重新渲染进而再次触发 effect。
解析示例:
错误写法(可能无限循环):
useEffect(() => {
fetchData(params); // params 是一个对象
}, [params]); // 每次渲染 params 都是新对象
正确写法:
const stableParams = useMemo(() => ({ id, page }), [id, page]);
useEffect(() => {
fetchData(stableParams);
}, [stableParams]); // 引用稳定,仅当 id 或 page 变化时执行
或直接监听原始值:
useEffect(() => {
fetchData({ id, page });
}, [id, page]);
这样做可确保 useEffect 仅在逻辑上真正需要更新时才执行,提高性能并避免副作用异常。

发表评论 (审核通过后显示评论):