What is the type of useRef if I want to referenciate a callback?

760 Views Asked by At

I am following Dan Abramov's approach to creating a custom hook for a basic setInterval use case. However, I'm having a hard time typing it in typescript. Especially, what should be the type of useRef? Here is the code in js, would love a transcription to typescript if possible

import React, { useState, useEffect, useRef } from 'react';

function useInterval(callback, delay) {
  const savedCallback = useRef();

  // Remember the latest callback.
  useEffect(() => {
    savedCallback.current = callback;
  }, [callback]);

  // Set up the interval.
  useEffect(() => {
    function tick() {
      savedCallback.current();
    }
    if (delay !== null) {
      let id = setInterval(tick, delay);
      return () => clearInterval(id);
    }
  }, [delay]);
}

In my code I would use it like this:

export interface DataProps<Type> {
  results: Type[];
  isLoading: boolean;
  LIMIT: number;
  offset: number;
}

export interface Pokemon {
  name: string;
  url: string;
}

const [data, setData] = useState<DataProps<Pokemon>>({
    results: [],
    isLoading: true,
    LIMIT: 20,
    offset: 0
  });

useInterval(
    async () => {
      try {
        const res = await fetch(
          `https://pokeapi.co/api/v2/pokemon?` +
            new URLSearchParams({
              limit: data.LIMIT + "",
              offset: data.offset + ""
            })
        );
        const { results } = await res.json();

        setData((prevValue) => ({
          ...prevValue,
          results: [...prevValue.results, ...results],
          isLoading: false,
          offset: prevValue.offset + prevValue.LIMIT
        }));
      } catch (err) {
        console.log("Fetch Error:", err);
      }
    },
    10000
  );
1

There are 1 best solutions below

0
On BEST ANSWER

You'd type your useRef to your callback type:

const savedCallback = useRef<typeof callback>();

If you're asking instead what your callback type should be, it would depend on what you want the function shape to be. Most common ones are () => Promise<void> | void for async or sync functions, or (...args: any) => Promise<void> | void for functions with arguments.