最近手上的一個案子要求所有的數據必須實時更新(每秒或每分鐘),且因為後端不用 socket 我需要自行在前端做處理,於是我就想著用 setInterval 來解決吧。這篇文章簡單紀錄一下使用 setInterval 用到的小技巧,方便之後回顧。
定時器的基本使用
最基本的 setInterval
使用方式如下:
useEffect(() => { const interval = setInterval(loadData, 1000); // 每隔一秒執行 loadData 這個 function return () => clearInterval(interval); }, []);
useEffect 中的 return
就是類式組件生命週期中的 componentWillUnmount
,通常用於取消訂閱、清除定時器…等。
刪除指定的定時器
有時候你的頁面會需要好幾個定時器,但你可能想指定清除其中一個的時候,可以用 useRef
將 interval ID 存下來,然後將之刪除:
import React, { useRef } from "react"; // ... const interval = useRef(null); useEffect(() => { interval.current = setInterval(loadData, 1000); }, []); const handlePause = () => { clearInterval(interval.current); }
如果想要跨頁面刪除的話,也可以將 interval ID 存進 context 裡面:
/* src/cotext.js */ import React from "react"; export default Context = React.createContext({ statusBarHeight: null, });
/* src/App.js */ import Context from "./context"; import React, { useState } from "react"; export default function App() { const [intervalId, setIntervalId] = useState(); return ( <Context.Provider value={{ intervalId, // 將要共用的變數(數據)添加在這 setIntervalId }} > <Column flex={1} style={{ position: "relative" }}> {body} </Column> </Context.Provider> ); }
/* /src/screen/Home.js */ import React, { useState, useEffect, useContext } from "react"; import Context from "../context"; export default function Home() { const { intervalId, setIntervalId } = useContext(Context); const interval = useRef(null); useEffect(() => { interval.current = setInterval(loadData, 1000); setIntervalId(interval.current); // 將 interval ID 存起來 }, []); // ... }
監聽路由變化的同時開關定時器
在路由變化的時候建立新的定時器,並且在前往別的頁面時將定時器清除:
import React, { useEffect, useRef } from "react"; import { View, Button } from "react-native"; import { useNavigation } from "@react-navigation/core"; export default function Home() { const navigation = useNavigation(); const interval = useRef(null); useEffect(() => { const unsubscribe = navigation.addListener("focus", () => { handlePause(); interval.current = setInterval(loadData, 1000); }); return unsubscribe; }, []); const loadData = () => { // ... } const handleNavigate = () => { clearInterval(interval.current); navigation.navigate("Clients"); } const handlePause = () => { clearInterval(interval.current); } return ( <View style={{ flex: 1 }}> <Button title="Clients" onPress={handleNavigate} /> </View> ) }
還有些等我慢慢回憶一下吧.. 忘記了,哈哈😂
Latest posts by pluto (see all)
- Expo 使用 EAS build 時遇到的坑及解決方式 - 2022 年 5 月 19 日
- Typora + PicGo-Core 使用 Github 作為筆記免費圖床的詳細圖文教學 - 2022 年 5 月 12 日
- [JS學習筆記] JS 中的傳值、傳址與淺拷貝、深拷貝 - 2022 年 5 月 8 日