react-native - React Native - 递归 setTimeout 重复运行某些东西
问题描述
下面的代码只是在加载数据时出现错误(特别是临时网络丢失)时出现的屏幕模型。我要做的是在挂载时运行“刷新”功能并每隔 10 秒继续运行一次,直到变量“在线”从“假”变为“真”。在这里我用一个按钮改变它,在真实屏幕中它将是一个异步调用来加载数据(如果加载了数据,它就会变成真的)。所以这个想法是继续尝试加载数据。
下面的代码中发生的情况是控制台每 10 秒记录一次“仍然离线”,但是当我按下按钮时,它会正确记录“重新在线”,但随后它会每 10 秒返回记录“仍然离线”。它应该清除超时,实际上屏幕将被卸载。
const [online, setOnline] = useState(false);
const [loading, setLoading] = useState(false);
const handleChange = () => {
setOnline(!online);
};
const refresh = useCallback(async () => {
setLoading(true);
// in the real screen the following will be assigned to 'online'
// const online = await loadData()
if (!online) {
setLoading(true);
setTimeout(refresh, 10000);
console.log('still offline');
} else {
setLoading(false);
clearTimeout(refresh);
console.log('back on line');
}
}, [online]);
useEffect(() => {
setTimeout(refresh, 10000);
}, [online, refresh]);
return (
<View>
{online ? <Text>Online</Text> : <Text>Offline</Text>}
{loading ? <Text>Loading</Text> : <Text>IDLE</Text>}
<Button title="Go Online" onPress={handleChange} />
</View>
);
解决方案
如果你想取消之前设置的定时器,你需要存储返回的定时器 id setTimeout
,你不能传递 setTimeout 回调函数本身。
const myTimerID = setTimeout(refresh, 10000);
...
clearTimeout(myTimerID)
看看我的样本
推荐阅读
- python - 从数据库导入数据时缺少列名(python + postgre sql)
- android-studio - 灰色资源 - xmlns:tools="http://schemas.android.com/tools" 和 xmlns:card_view="http://schemas.android.com/apk/res-auto"
- javascript - Recharts折线图不会在数据更新时绘制新点
- java - 如何仅知道模数和指数将公钥保存到密钥库文件?
- css - 更改角材料文本框的原色
- webhooks - 从代码为 Jenkins 多分支管道配置 webhook
- java - Android 应用程序在 Android Studio 模拟器中不断崩溃
- java - diff.getYears() 返回 0。根据 LocalDate 出生日期计算年龄
- java - 如何基于另一个本地存储通过 selenium 在本地存储中正确写入数据?
- java - 如何使用 Mockito 模拟由 Spring 应用程序上下文创建的对象以进行单元测试覆盖?