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

ReactJS - use localStorage as a dependency for useEffect causes infinite loop

此代码在第 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,循环就会消失,我想知道为什么?我根本没有在代码中更改它。

试试这个

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);
    }
  });
};

userInfo实际上正在改变。

它是一个函数式组件,所以组件内的所有代码在每次渲染时都会 运行,因此,userInfo 在每次渲染时都会 re-created,因为它是未声明为引用(useRef),或者更常见的是,声明为状态(useState)。

流程如下:

  1. 组件挂载。
  2. useEffect 运行s getData。第二个useEffect也是运行s.
  3. getData 将用 setScoreData 更新 scoreData 状态。后者将触发 re-render,并且 scoreData 已更改,因此第二个 useEffect 将 运行.
  4. 渲染发生时,组件中的所有代码都将 运行,包括 userInfo 声明(创建对它的新引用,除非 localStorage.getItem("user_info") 返回 undefined).
  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]);