如何在 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>;
}

关键点解析:

  1. 依赖数组必须完整:effect 中用到的所有外部变量(包括 props 和状态)都应出现在依赖数组中,否则可能使用过期的值。
  2. 避免在 effect 中直接修改依赖项:如果 effect 中调用的函数会更新某个状态,而该状态又作为 prop 传回组件,可能造成无限循环。此时应检查逻辑是否合理,或使用 useCallback 稳定回调函数。
  3. 使用 ESLint 插件:React 官方推荐使用 eslint-plugin-react-hooks,它会自动检查依赖数组是否完整,帮助避免常见错误。

例如,错误写法:

// ❌ 危险:可能造成无限循环
useEffect(() => {
  setUser({ id: userId, name: '...' });
}, [userId]);

// 如果父组件根据 user 状态重新渲染并传入新的 userId(即使值相同但引用不同),
// 就可能不断触发 effect。

总结:正确声明依赖、理解数据流、避免副作用中产生副作用,是使用 useEffect 的核心原则。

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

昵称:
邮箱:
内容: