DEV Community

adelchms96
adelchms96

Posted on • Edited on

UseFetch hook for react js.

hello guys, will show you a custom hook for handling async call.
useFetch hook take a callback as first argument and callback params for rest arguments.
here it's:

const useFetch = (cb, ...params) => {
  const isMounted = useRef();
  const [response, setResponse] = useState();
  const [loading, setLoading] = useState(false);
  //const [error, setError] = useState();

  return {
    response,
    loading,
    isMounted,
    reset: () => setResponse(),
    fetch: async (reload = false) => {
      try {
        isMounted.current = true;
        if (!response || reload) setLoading(true);
        const data = await cb(...params);
        if (isMounted.cuurent) {
          if (data) setResponse(data)
        }
      } catch (error) {
        errorNotification(error); // do something with the error
        // or u can add setError(error)
      }
      finally{
     setLoading(false);
       }
    }
  };
};

Usage:

const UserProfile = ({ id }) => {
  const { response, loading, fetch, isMounted } = useFetch(getUserProfile, id);
  useEffect(() => {
    fetch();
    return () => {
      isMounted.current = false;
    };
  }, []);
  return (
    <>{loading ? <p>Loading...</p> : response && <p>{response.userName}</p>}</>
  );
};

Note: isMounted is used to detect component unmount for not firing unnecessary state update.
hope you like it,thanks.

Top comments (1)

Collapse
 
jenbuska profile image
jEnbuska • Edited

Looks nice =)
I was looking for how other people are solving this same problem.
There is three changes I would make to that useFetch logic.

  • isMounted does not need to be handled outside of useFetch hook
  • useFetch 'fetch' return value overlaps with window.fetch
  • multiple request race condition should be handled somehow

If you are interested, checkout the useFetch solution that I have been using github.com/jEnbuska/scratches/blob...