我试图仅在安装/卸载时设置一个时间间隔,但允许回调从状态中获取一个变量。
我有这样的代码:
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
传递给第二个参数,并通过清除和间隔设置 console.log
,我的控制台会输出类似这样的内容:
clearing interval undefined
set interval to 5
set interval to 7
因此,它似乎运行了卸载,然后运行了两次效果,而没有再次清除。这会导致双重 axios 调用。
最佳答案
您可以使用 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);
}
}, []);
关于reactjs - 如何通过 React Hooks 使用一次效果,但仍然使用状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56029648/