我使用 setTimeout 和回调函数每 5 秒间隔自动刷新一个页面(例如 Page1)。
当我移动到新页面(例如第 2 页)时,它会进入新页面,几秒钟后再次返回到第 1 页。
我尝试了 window beforeunload 事件侦听器,反应 useBeforeUnload,但没有任何效果。这是重现该问题的最少代码。
const SampleTestStats = () => {
let allowStateChange = true;
let sampleTimeOut = null;
let SAMPLE_TEST_STATS_REFRESH_TIME = 5000;
const [result, setResult] = useState([{ tid: 0, tcname: "none"},]);
const user = JSON.parse(localStorage.getItem('user'));
function refreshPage() {
sampleTimeOut = setTimeout(refreshPage, SAMPLE_TEST_STATS_REFRESH_TIME);
window.location.href = "/components/view/sampletest/stats";
}
useBeforeUnload(
React.useCallback(() => {
console.log('In useBeforeUnload');
allowStateChange = false;
clearTimeout(sampleTimeOut);
})
);
const fetchTestStats = async () => {
try {
const res = await axios.post('/test/current/active/data',
{uid: user.uid, email: user.email} ,
{headers: {
'Authorization': user.jwt,
}}).then(
function (res) {
if(res.status === 200) {
if(allowStateChange) {
let newResult = {tid: res.data[0].tid, tcname: res.data[0].testname};
setResult([newResult]);
}
}
});
}catch(err) {
}
}
useEffect ( () => {
fetchTestStats();
}, []);
sampleTimeOut = setTimeout(refreshPage, SAMPLE_TEST_STATS_REFRESH_TIME);
return (`My simple refresh test page, test id = ${result[0].tid} and test name = ${result[0].tcname}.`);
}
有人可以帮助我吗,当我再次自动移动到新页面 Page2 时,它不应该返回到旧页面 Page1。
我相信您看到的问题是因为当您的
useCallback
值更新时,用 sampleTimeOut
包装的函数没有更新。这是因为您没有传递依赖项数组,因此回调在安装后不会重新计算其任何内部结构。这意味着您将原始 null
传递给您的 clearTimeout
函数,因此您的超时不会被正确清除。
我有一些可能有帮助的建议。
首先,我建议将所有刷新逻辑放入
useEffect
中,并调用清理函数来清除超时。这样,每当组件卸载时,它都会清除所有活动超时。
此外,还有一个方便的
setInterval
函数,可以按照您定义的设定时间间隔运行超时。您可以使用 clearInterval
以类似的方式清除它。
最后,调用
window.location.reload()
是重新加载页面的一种更简洁的方式,并且更加模块化,允许您在任何路线上使用此组件。
这样的东西可以工作:
const SampleTestStats = () => {
...
let SAMPLE_TEST_STATS_REFRESH_TIME = 5000;
function refreshPageInterval() {
return setInterval(() => {
window.location.reload()
}, SAMPLE_TEST_STATS_REFRESH_TIME)
}
useEffect ( () => {
fetchTestStats();
const interval = refreshPageInterval();
return () => clearInterval(interval);
}, []);
...
}