Jalankan fungsi secara berkala dengan setInterval

const useInterval = (callback, interval, immediate) => {
  const ref = useRef();

  // keep reference to callback without restarting the interval
  useEffect(() => {
    ref.current = callback;
  }, [callback]);

  useEffect(() => {
    // when this flag is set, closure is stale
    let cancelled = false;

    // wrap callback to pass isCancelled getter as an argument
    const fn = () => {
      ref.current(() => cancelled);
    };

    // set interval and run immediately if requested
    const id = setInterval(fn, interval);
    if (immediate) fn();

    // define cleanup logic that runs
    // when component is unmounting
    // or when or interval or immediate have changed
    return () => {
      cancelled = true;
      clearInterval(id);
    };
  }, [interval, immediate]);
};

//Then you can use the hook like this:

const [temperature, setTemperature] = useState();

useInterval(async (isCancelled) => {
  try {
    const response = await fetch('urlToWeatherData');
    // check for cancellation after each await
    // to prevent further action on a stale closure
    if (isCancelled()) return;

    if (response.status !== 200) {
      // throw here to handle errors in catch block
      throw new Error(response.statusText);
    }

    const [{ temperature }] = await response.json();
    if (isCancelled()) return;

    console.log(temperature);
    setTemperature(temperature);
  } catch (err) {
    console.log('Fetch Error:', err);
  }
}, 15000, true);
Gotifly