英文:
Infinite loop using useEffect, useState and useSWR
问题
const [useStateVar, setUseStateVar] = useState({});
const { data } = useSWR("demo/data", fetcher, { refreshInterval: 1000 });
useEffect(() => {
// Ensure data exists before updating state
if (data !== undefined) {
setUseStateVar((prevState) => {
// Update the state based on the previous state
return { ...prevState, newData: data };
});
}
}, [data]);
英文:
const [ useStateVar, setUseStateVar ] = useState({})
const { data } = useSWR("demo/data", fetcher, {refreshInterval: 1000})
useEffect(() => {setUseStateVar(useStatevar+1)}, [data])
I believe the above code runs like this:
When the data first update at a 1s frequent, it triggers the useEffect()
to update useStateVar
using setUseStateVar
, once the useStatevar
is updated, the data
update again, when the data
updated, it triggers the useEffect()
, so it created an infinite loop to the browser to update the value and hit the maximum.
I aim to get the updated data using useSWR()
and update some variables, and reload the component while data
is updated.
How can I achieve it without creating an infinite loop?
答案1
得分: 1
为了防止你的代码中出现无限循环,你可以使用 useRef
钩子来跟踪由 useSWR
获取的数据的先前值。这样,你可以将当前数据与先前值进行比较,并在数据发生变化时有条件地更新 useStateVar
。以下是如何实现的代码示例:
import { useState, useEffect, useRef } from 'react';
import useSWR from 'swr';
const Component = () => {
const [useStateVar, setUseStateVar] = useState({});
const { data } = useSWR("demo/data", fetcher, { refreshInterval: 1000 });
// 创建一个 ref 以跟踪先前的数据值
const prevDataRef = useRef();
useEffect(() => {
// 检查 prevDataRef.current 是否存在并且数据是否发生了变化
if (prevDataRef.current && data !== prevDataRef.current) {
// 仅在数据发生变化时更新 useStateVar
setUseStateVar(prevState => {
// 根据新数据修改状态
// 例如,你可以将新数据与先前状态合并
return { ...prevState, ...data };
});
}
// 使用当前数据值更新 prevDataRef 以供下一次比较
prevDataRef.current = data;
}, [data]);
// 组件其余代码
return (
// JSX 元素
);
}
useRef
钩子用于创建 prevDataRef,它保存了先前的数据值。在 useEffect
钩子内部,我们检查 prevDataRef.current
是否存在(即不为 null 或 undefined),以及当前数据值是否与先前的数据值不同。
如果数据发生变化,我们通过将新数据与先前状态合并(你可以根据具体的用例修改此部分)来更新 useStateVar
状态。
通过比较当前数据和先前数据的值,我们确保只有在 useSWR
获取的数据真正发生变化时才会更新 useStateVar
状态,从而避免了无限循环问题。
英文:
To prevent the infinite loop in your code, you can use the useRef
hook to keep track of the previous value of the data fetched by useSWR
. This way, you can compare the current data with the previous value and conditionally update the useStateVar
only when the data changes. Here's how you can achieve it:
import { useState, useEffect, useRef } from 'react';
import useSWR from 'swr';
const Component = () => {
const [useStateVar, setUseStateVar] = useState({});
const { data } = useSWR("demo/data", fetcher, { refreshInterval: 1000 });
// Create a ref to keep track of the previous data value
const prevDataRef = useRef();
useEffect(() => {
// Check if prevDataRef.current exists and if the data has changed
if (prevDataRef.current && data !== prevDataRef.current) {
// Update the useStateVar only when the data changes
setUseStateVar(prevState => {
// Modify the state based on the new data
// For example, you can merge the new data with the previous state
return { ...prevState, ...data };
});
}
// Update the prevDataRef with the current data value for the next comparison
prevDataRef.current = data;
}, [data]);
// Rest of your component code
return (
// JSX elements
);
}
the useRef
hook is to create prevDataRef, which holds the previous value of data. Inside the useEffect
hook, we check if the prevDataRef.current
exists (i.e., it is not null or undefined) and if the current data value is different from the previous one.
If there's a change in the data, we update the useStateVar
state by merging the new data with the previous state (you can modify this part based on your specific use case).
comparing the current and previous data values, we ensure that the useStateVar
state is only updated when there's a genuine change in the data fetched by useSWR
, avoiding the infinite loop issue.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论