How to use custom hook (fetch) with typescript

Viewed 2829

I have created a custom hooks called useFetch.

import { useState, useEffect } from 'react'

export const useFetch = (url: string, options?: object) => {
    const [response, setResponse] = useState(null);
    const [error, setError] = useState(null);

    useEffect(() => {
      const fetchData = async () => {
        try {
          const res = await fetch(url, options);
          const json = await res.json();
          setResponse(json);
        } catch (error) {
          setError(error);
        }
      };
      fetchData();
    }, []);

    return { response, error };
  };

But destructuring useFetch and typing it with typescript fails as if the answer may be null

import React, { FunctionComponent } from 'react'
import { useFetch } from '../../hooks/useFetch'

export const ListOfMovies: FunctionComponent = () => {
    const { response, error }: { response: object, error: object} = useFetch("http://www.omdbapi.com/?apikey=****&s=batman&page=2")
    
    if (!response) return <h2>Loading...</h2>

    if (error) return <h2>Error</h2>

    return (
        <div>
            <h2>Lista de pelĂ­culas</h2>
            {response.Search.map(movie => (
                <p>{movie.Title}</p>
            ))}
        </div>
    )
}
2 Answers
  1. You can try to set your response manually as 'any'
import { useState, useEffect } from 'react'

export const useFetch = (url: string, options?: object) => {
    const [response, setResponse] = useState<any>(null);
    const [error, setError] = useState<any>(null);
    ...
  };

...

  1. If you don't like 'any' try using generic.

    export const useFetch = <T>(url: string, options?: object) => {
        const [response, setResponse] = useState<T>(null);
        const [error, setError] = useState<T>(null);
        ...
      };
    

    }

So the function invocation will look like

    type YourCustomType = {response: ..., error: ...}
    const { response, error }: { response: object, error: object} = 
    useFetch<YourCustomType>("http://www.omdbapi.com/?apikey=****&s=batman&page=2");

}

You have set the initial value of response and error as null therefore you are getting this warning.

Try this:

const [response, setResponse] = useState({});
const [error, setError] = useState({});
Related