1

I'm trying to write a custom fetch hook, but I guess im missing something.

import React, { useContext } from 'react';
import { Context } from "../components/context";

const fetchHook = async(url: string, bearer: string, method: string, body: any ) => {
    const { global } = useContext(Context) as {global: any};
    let headers = {'cache-control': 'no-cache', 'Content-Type': 'application/json' };
    if (bearer) headers = {...headers, ...{'Authorization': bearer}}
    if (method === 'GET') return await fetch(global.apiUrl + url, {method, headers});
    else return await fetch(global.apiUrl + url, {method, headers, body});
}

export { fetchHook }

The error im getting is Line 5: React Hook "useContext" is called in function "fetchHook" which is neither a React function component or a custom React Hook function react-hooks/rules-of-hooks

UPDATE:

import React, { useContext } from 'react';
import { Context } from "../components/context";


const useFetch = (url: string, bearer: string, method: string, body: any) => {

    const { global } = useContext(Context) as {global: any};
    let headers = {'cache-control': 'no-cache', 'Content-Type': 'application/json' };
    if (bearer) headers = {...headers, ...{'Authorization': bearer}}

    const [response, setResponse] = React.useState(null);
    const [error, setError] = React.useState(null);
    const apiUrl = global.apiUrl;

    React.useEffect(() => {
      const fetchData = async () => {
        try {
            let res; 
            if (method === 'GET') res = await fetch(apiUrl + url, {method, headers});
            else res = await fetch(global.apiUrl + url, {method, headers, body});
            setResponse(await res.json());
        } catch (error) {
          setError(error);
        }
      };
      fetchData();
    }, []);

    return { response, error };
  };

  export { useFetch } 

The only warning I get now I about a missing dependency warning but I'm not sure how to fix it. Should I be passing all the dependencies into the square brackets of useEffect()?? I'm just not sure? Line 27: React Hook React.useEffect has missing dependencies: 'apiUrl', 'body', 'global.apiUrl', 'headers', 'method', and 'url'. Either include them or remove the dependency array

2
  • 1
    Hooks must be used only in react function component (React.FC) Commented Oct 4, 2019 at 7:18
  • How are you using fetchHook Commented Oct 4, 2019 at 7:33

1 Answer 1

3

You are getting this warning because according to the Rules of hooks, a custom hook name must start with use.

As mentioned the docs of custom hooks

A custom Hook is a JavaScript function whose name starts with ”use” and that may call other Hooks.

You won't receive the error if you rename the hook to

const useFetchHook = async(url: string, bearer: string, method: string, body: any ) => {
    const { global } = useContext(Context) as {global: any};
    let headers = {'cache-control': 'no-cache', 'Content-Type': 'application/json' };
    if (bearer) headers = {...headers, ...{'Authorization': bearer}}
    if (method === 'GET') return await fetch(global.apiUrl + url, {method, headers});
    else return await fetch(global.apiUrl + url, {method, headers, body});
}

export { useFetchHook }

Also one thing you must keep in mind is that if you execute async code within the custom hook directly, it will be executed on every render. A better way is to maintain state and fetch the data within useEffect and update the state when the data is received.

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

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.