我陷入了 react.js 的无限循环。如何解决这个问题?
I Got Stuck in infinite loop in react.js. How to resolve this?
我陷入了 react.js 的无限循环。如何解决?
useEffect(() => {
fetch("https://react-http-d55a9-default-rtdb.firebaseio.com/todo.json")
.then((response) => {
return response.json();
})
.then((data) => {
console.log(data);
setUsersList((prev) => [...prev]); //cause of infinite loop
});
}, [usersList]);
传递给 useEffect
的依赖列表决定了效果何时再次 运行。无限循环正在发生,因为此效果会导致 usersList
发生变化,从而再次触发效果 运行。
由于此效果不使用任何其他变量,因此它的依赖列表中不需要任何内容:
useEffect(() => {
fetch(...)
// ...
}, []); // leave this empty, so the effect only runs when the component mounts
如果你的 URL 依赖于道具或其他东西,那么你希望它在依赖列表中:
useEffect(() => {
fetch(`https://example.com/todo/${props.id}`)
.then(...)
// Since the URL depends on the id prop, the effect should re-run if it changes
}, [props.id]);
你有一个无限循环,因为你的 useEffect
依赖数组有 usersList
并且同时你在你的 useEffect
函数中更新这个变量。所以当组件安装时你的 useEffect
运行s 更新你的 usersList
这使得 useEffect
运行 再次更新你的 usersList
这使得再次 运行 等等...
要解决此问题,请从依赖项数组中删除 usersList
并使用一个空数组:[]
。如果你这样做,你的 useEffect
将 运行 一次,当你的组件安装时。
根据提出的问题,您希望 userList 每次更新时都被监视。我们可以做的是再定义一个状态变量,如代码中提到的 isFetched,或者如果您使用的是 redux,则可以将其放在那儿,因为如果我们只观察 userList 变量,那么它会陷入无限循环,因为设置 userList 是发生在 useEffect 本身。在 isFetched 的帮助下,我们可以管理何时调用 api 以及每当标志为 false 时调用 api.
现在在代码中我又添加了一个状态变量作为 setCount,因为我不知道你想调用你的 api 多少次。所以你可以把你的条件放在那里,当你的条件满足时停止调用。
function App() {
const [userList, setUserList] = useState([]);
const [isFetched, setIsFetched] = useState(false);
const [, setCount] = useState(3);
const callApiPending = useCallback(()=>{
fetch("https://react-http-d55a9-default-rtdb.firebaseio.com/todo.json")
.then((response) => response.json())
.then((json) => {
setUserList((prev) => [...prev, ...json]);
setCount((cnt) => {
if(cnt - 1 === 0){
setIsFetched(true);
}
return cnt - 1;
});
});
}, []);
useEffect(() => {
if (!isFetched) {
callApiPending();
}
}, [isFetched, userList, callApiPending]);
return <div>Executing....</div>;
}
如果 usersList 发生变化,您 运行 获取。即使 userList 的内容与之前的内容相同,javascript 也会按其更改进行解释。试试这个。
[1,2,3] == [1,2,3]
可能 return 错误。您可以使用用于检查是否获取数据的标志而不是使用数组。
我陷入了 react.js 的无限循环。如何解决?
useEffect(() => {
fetch("https://react-http-d55a9-default-rtdb.firebaseio.com/todo.json")
.then((response) => {
return response.json();
})
.then((data) => {
console.log(data);
setUsersList((prev) => [...prev]); //cause of infinite loop
});
}, [usersList]);
传递给 useEffect
的依赖列表决定了效果何时再次 运行。无限循环正在发生,因为此效果会导致 usersList
发生变化,从而再次触发效果 运行。
由于此效果不使用任何其他变量,因此它的依赖列表中不需要任何内容:
useEffect(() => {
fetch(...)
// ...
}, []); // leave this empty, so the effect only runs when the component mounts
如果你的 URL 依赖于道具或其他东西,那么你希望它在依赖列表中:
useEffect(() => {
fetch(`https://example.com/todo/${props.id}`)
.then(...)
// Since the URL depends on the id prop, the effect should re-run if it changes
}, [props.id]);
你有一个无限循环,因为你的 useEffect
依赖数组有 usersList
并且同时你在你的 useEffect
函数中更新这个变量。所以当组件安装时你的 useEffect
运行s 更新你的 usersList
这使得 useEffect
运行 再次更新你的 usersList
这使得再次 运行 等等...
要解决此问题,请从依赖项数组中删除 usersList
并使用一个空数组:[]
。如果你这样做,你的 useEffect
将 运行 一次,当你的组件安装时。
根据提出的问题,您希望 userList 每次更新时都被监视。我们可以做的是再定义一个状态变量,如代码中提到的 isFetched,或者如果您使用的是 redux,则可以将其放在那儿,因为如果我们只观察 userList 变量,那么它会陷入无限循环,因为设置 userList 是发生在 useEffect 本身。在 isFetched 的帮助下,我们可以管理何时调用 api 以及每当标志为 false 时调用 api.
现在在代码中我又添加了一个状态变量作为 setCount,因为我不知道你想调用你的 api 多少次。所以你可以把你的条件放在那里,当你的条件满足时停止调用。
function App() {
const [userList, setUserList] = useState([]);
const [isFetched, setIsFetched] = useState(false);
const [, setCount] = useState(3);
const callApiPending = useCallback(()=>{
fetch("https://react-http-d55a9-default-rtdb.firebaseio.com/todo.json")
.then((response) => response.json())
.then((json) => {
setUserList((prev) => [...prev, ...json]);
setCount((cnt) => {
if(cnt - 1 === 0){
setIsFetched(true);
}
return cnt - 1;
});
});
}, []);
useEffect(() => {
if (!isFetched) {
callApiPending();
}
}, [isFetched, userList, callApiPending]);
return <div>Executing....</div>;
}
如果 usersList 发生变化,您 运行 获取。即使 userList 的内容与之前的内容相同,javascript 也会按其更改进行解释。试试这个。
[1,2,3] == [1,2,3]
可能 return 错误。您可以使用用于检查是否获取数据的标志而不是使用数组。