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
);
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.