首页 > 解决方案 > 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>
  );

标签: react-nativesettimeout

解决方案


如果你想取消之前设置的定时器,你需要存储返回的定时器 id setTimeout,你不能传递 setTimeout 回调函数本身。

const myTimerID = setTimeout(refresh, 10000);
...
clearTimeout(myTimerID)

看看我的样本


推荐阅读