3

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>
    )
}
1
  • I think the generic solution given in the accepted answer is wrong and will give syntax errors. Could you verify if the generic approach worked for you? Commented Jul 17, 2020 at 17:23

2 Answers 2

2
  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");

}
Sign up to request clarification or add additional context in comments.

3 Comments

Any shouldn't be suggested as it defeats a major goal of using Typescript and should be used when there are no other options.
And there are always other options.
The generic version is preferable in many instances while avoiding any.
-1

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({});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.