ReactJS - 使用 localStorage 作为 useEffect 的依赖项会导致无限循环

发布于 2025-01-09 02:44:16 字数 856 浏览 1 评论 0原文

此代码在 console.log 行给了我无限循环

const userInfo = JSON.parse(localStorage.getItem("user_info"));
const [filterSemester, setFilterSemester] = useState(SEMESTERS[0]);
const [scoreData, setScoreData] = useState(null);

useEffect(() => {
  getData();
}, [userInfo, filterSemester]);

useEffect(() => {
  console.log("scoreData: ", scoreData);
}, [scoreData]);

const getData = () => {
  const params = {
    student_id: userInfo?.student_info?.id,
    school_year_id:
      userInfo?.student_info?.class_info?.grade_info?.school_year_id,
    semester: filterSemester.key,
  };
  getStudyInfoBySchoolYear(params).then((res) => {
    if (res?.status === 200) {
      setScoreData(res?.data?.data);
    }
  });
};

如果我从第一个 useEffect 的依赖项数组中删除 userInfo,循环就会消失,我想知道为什么?我在代码中根本没有改变它。

This code give me infinite loop at line console.log

const userInfo = JSON.parse(localStorage.getItem("user_info"));
const [filterSemester, setFilterSemester] = useState(SEMESTERS[0]);
const [scoreData, setScoreData] = useState(null);

useEffect(() => {
  getData();
}, [userInfo, filterSemester]);

useEffect(() => {
  console.log("scoreData: ", scoreData);
}, [scoreData]);

const getData = () => {
  const params = {
    student_id: userInfo?.student_info?.id,
    school_year_id:
      userInfo?.student_info?.class_info?.grade_info?.school_year_id,
    semester: filterSemester.key,
  };
  getStudyInfoBySchoolYear(params).then((res) => {
    if (res?.status === 200) {
      setScoreData(res?.data?.data);
    }
  });
};

If I remove userInfo from the dependency array of the first useEffect, the loop will gone, I wonder why? I didn't change it at all in the code.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

好听的两个字的网名 2025-01-16 02:44:16

userInfo 实际上正在发生变化。

它是一个功能组件,因此组件内部的所有代码都将在每次渲染上运行,因此,userInfo 会在每次渲染上重新创建,因为它没有声明为引用(使用 < code>useRef),或更常见的是,作为状态(使用 useState)。

流程如下:

  1. 元件安装。
  2. 第一个 useEffect 运行 getData。第二个 useEffect 也会运行。
  3. getData 将使用 setScoreData 更新 scoreData 状态。后者将触发重新渲染,并且 scoreData 也已更改,因此第二个 useEffect 将运行。
  4. 渲染发生时,组件中的所有代码都将运行,包括 userInfo 声明(创建对其的新引用,除非 localStorage.getItem("user_info")返回未定义)。
  5. React 检测到 userInfo 已更改,因此第一个 useEffect 将再次运行。
  6. 该过程从步骤 3 开始重复。

您可以将您替换

const userInfo = JSON.parse(localStorage.getItem("user_info"));

  const userInfo = React.useRef(JSON.parse(localStorage.getItem("user_info")));

并将您

useEffect(() => {
  getData();
}, [userInfo, filterSemester]);

替换为

  useEffect(() => {
    getData();
  }, [userInfo.current, filterSemester]);

userInfo is actually changing.

It is a functional component, so all the code that is inside the component will run on every render, thus, userInfo gets re-created on every render, because it was not declared as a reference (with useRef) or, more commonly, as a state (with useState).

The flow is as follows:

  1. The component mounts.
  2. The first useEffect runs getData. The second useEffect also runs.
  3. getData will update scoreData state with setScoreData. This latter will trigger a re-render, and also scoreData has changed, so the second useEffect will run.
  4. When the render takes place, all the code within your component will run, including the userInfo declaration (creating a new reference to it, unless localStorage.getItem("user_info") is returning undefined).
  5. React detects userInfo as changed, so the first useEffect will run again.
  6. The process repeats from step 3.

You could replace your

const userInfo = JSON.parse(localStorage.getItem("user_info"));

with

  const userInfo = React.useRef(JSON.parse(localStorage.getItem("user_info")));

and your

useEffect(() => {
  getData();
}, [userInfo, filterSemester]);

with

  useEffect(() => {
    getData();
  }, [userInfo.current, filterSemester]);
老子叫无熙 2025-01-16 02:44:16

试试这个

const userInfo = JSON.parse(localStorage.getItem("user_info"));
const [filterSemester, setFilterSemester] = useState(SEMESTERS[0]);
const [scoreData, setScoreData] = useState(null);

useEffect(() => {
  getData();
}, [localStorage.getItem("user_info"), filterSemester]);

useEffect(() => {
  console.log("scoreData: ", scoreData);
}, [scoreData]);

const getData = () => {
  const params = {
    student_id: userInfo?.student_info?.id,
    school_year_id:
      userInfo?.student_info?.class_info?.grade_info?.school_year_id,
    semester: filterSemester.key,
  };
  getStudyInfoBySchoolYear(params).then((res) => {
    if (res?.status === 200) {
      setScoreData(res?.data?.data);
    }
  });
};

try this

const userInfo = JSON.parse(localStorage.getItem("user_info"));
const [filterSemester, setFilterSemester] = useState(SEMESTERS[0]);
const [scoreData, setScoreData] = useState(null);

useEffect(() => {
  getData();
}, [localStorage.getItem("user_info"), filterSemester]);

useEffect(() => {
  console.log("scoreData: ", scoreData);
}, [scoreData]);

const getData = () => {
  const params = {
    student_id: userInfo?.student_info?.id,
    school_year_id:
      userInfo?.student_info?.class_info?.grade_info?.school_year_id,
    semester: filterSemester.key,
  };
  getStudyInfoBySchoolYear(params).then((res) => {
    if (res?.status === 200) {
      setScoreData(res?.data?.data);
    }
  });
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文