如何在 React 中正确地使用 useEffect 来监听某个 prop 的变化并避免无限循环?
如何在 React 中正确地使用 useEffect 来监听某个 prop 的变化并避免无限循环?
在 React 中,useEffect 用于在函数组件中执行副作用操作(如数据获取、订阅等)。当我们想监听某个 prop 的变化时,需要将其添加到依赖数组中。但如果不当使用(例如在 effect 中更新该 prop 所依赖的状态,而该状态又作为 prop 传入),可能会触发无限循环。
正确做法如下:
import React, { useEffect, useState } from 'react';
function MyComponent({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
// 当 userId 变化时重新获取用户信息
fetchUser(userId).then(setUser);
}, [userId]); // 依赖数组中只包含 userId
return <div>{user?.name}</div>;
}
关键点解析:
- 依赖数组必须完整:effect 中用到的所有外部变量(包括 props 和状态)都应出现在依赖数组中,否则可能使用过期的值。
- 避免在 effect 中直接修改依赖项:如果 effect 中调用的函数会更新某个状态,而该状态又作为 prop 传回组件,可能造成无限循环。此时应检查逻辑是否合理,或使用 useCallback 稳定回调函数。
- 使用 ESLint 插件:React 官方推荐使用 eslint-plugin-react-hooks,它会自动检查依赖数组是否完整,帮助避免常见错误。
例如,错误写法:
// ❌ 危险:可能造成无限循环
useEffect(() => {
setUser({ id: userId, name: '...' });
}, [userId]);
// 如果父组件根据 user 状态重新渲染并传入新的 userId(即使值相同但引用不同),
// 就可能不断触发 effect。
总结:正确声明依赖、理解数据流、避免副作用中产生副作用,是使用 useEffect 的核心原则。

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