我试图仅在安装/卸载时设置一个间隔,但是允许回调从状态中获取一个变量。
我有这样的代码:
const [cachedData, setCachedData] = useState(false);
async function refreshData() {
const data = await axios('http://www.example.com/');
setCachedData(data);
}
useEffect(() => {
let interval;
async function fetch() {
await refreshData();
interval = setInterval(refreshData,5000);
console.log('set interval to', interval)
}
fetch();
return () => {
console.log('clearing interval', interval);
clearInterval(interval);
}
}, []);
我遇到了22个问题。 useEffect
的第二个参数指出要注意哪些变量。我读过使其成为一个空数组,使得它只能安装/卸载,而不是进行任何状态更新。我发现的问题是,这样做意味着refreshData
无法访问cachedData
,所以我不知道我有有效的数据(避免在一段时间内避免XHR请求)。如果我将cachedData
传递到useEffect
的第二个参数中,它将具有该变量,但运行得比预期的多。不确定是否可以解决此问题。
我应该注意,如果我将cachedData
传递给第二个arg,并且将console.log
传递给间隔的清除和设置,则我的控制台将输出如下内容:
clearing interval undefined
set interval to 5
set interval to 7
因此,它似乎运行了卸载,然后效果重复了两次,而无需再次清除。这会导致两次axios呼叫。
答案 0 :(得分:1)
您可以使用ref来获取当前的cachedData
,如下所示:
const [cachedData, setCachedData] = useState(false);
const cachedDataRef = useRef(cachedData);
useEffect(() => {
// Update ref in effect so that render has no side effects.
cachedDataRef.current = cachedData;
}, [cachedData]);
useEffect(() => {
async function refreshData() {
if (cachedDataRef.current) {
// do something different
} else {
const data = await axios('http://www.example.com/');
setCachedData(data);
}
}
let interval;
async function fetch() {
await refreshData();
interval = setInterval(refreshData,5000);
console.log('set interval to', interval)
}
fetch();
return () => {
console.log('clearing interval', interval);
clearInterval(interval);
}
}, []);