这段代码在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
,循环就会消失,我想知道为什么?我根本没有在代码中更改它。
userInfo
实际上正在发生变化。
它是一个功能性组件,因此组件中的所有代码都将在每次渲染中运行,因此,userInfo
在每次渲染时都会被重新创建,因为它没有被声明为引用(使用useRef
(,或者更常见的是,它没有被宣布为状态(使用useState
(。
流程如下:
- 组件安装
- 第一个
useEffect
运行getData
。第二个useEffect
也运行 getData
将用setScoreData
更新scoreData
状态。后者将触发重新渲染,并且scoreData
也已更改,因此将运行第二个useEffect
- 当渲染发生时,组件中的所有代码都将运行,包括
userInfo
声明(创建对它的新引用,除非localStorage.getItem("user_info")
返回undefined
( - React检测到
userInfo
已更改,因此第一个useEffect
将再次运行 - 该过程从步骤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]);
尝试这个
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);
}
});
};