DEV Community

Rafi
Rafi

Posted on

Simple hook to deal with async function calls

For smaller react projects I wanted something simple to deal with asynchronous function calls like fetch API. Rather than littering the component with useState for dealing with loader, error and response I wrote a really simple hook

import { useState, useCallback } from 'react';

function useAsync(handleAsync, initialResponse = {}) {
  const [isLoading, setLoading] = useState(false);
  const [error, setError] = useState(false);
  const [response, setResponse] = useState(initialResponse);

  const fetchValue = useCallback(
    async (options) => {
      setLoading(true);
      setError(false);

      try {
        const apiResponse = await handleAsync(options);
        setResponse(apiResponse);
        setLoading(false);
      } catch (error) {
        setError(true);
        setLoading(false);
        setResponse(error);
      }
    },
    [setError, setLoading, setResponse, handleAsync]
  );

  return {
    response,
    isLoading,
    error,
    fetchValue,
  };
}

export default useAsync;

So I can use this as follows

const { response, fetchValue, isLoading, error } = useAsync(signupUser);

const handleSubmit = useCallback(() => {
  fetchValue({ email, password });
}, [email, password, fetchValue]);
export const signupUser = async ({ email, password }) => {
  const response = await fetch(`dev.to/signup`, {
    credentials: "include",
    method: "POST",
    headers: {
      "Content-type": "application/json",
    },
    body: JSON.stringify({
      email,
      password,
    }),
  });

  if (!response.ok) {
    throw new Error(response);
  }

  return response.json();
};

react-async does provide something similar but it had lot of other functionality that I won't need. So going with a simple hook instead of a complete library just for this alone seemed like a better choice for me.

Top comments (4)

Collapse
 
rafi993 profile image
Rafi • Edited

The initialResponse is just bad naming. I should have named it something else (but I could not think of anything at the moment). It is just the initial value I want the response state to have.

Collapse
 
rafi993 profile image
Rafi • Edited

all of this could also be tracked in a single state too. But I just separated it just to be explicit. Thanks for your feed back :)

Collapse
 
instinct profile image
Instinct

Hey, need some help!

I have basic knowledge of react but I want to dive deeper. Can you suggest me a book where I can learn advanced react?

Collapse
 
rafi993 profile image
Rafi

If you know basic react and want to dive deeper I would suggest you to read react docs. It is really well organized. And build things with react as you learn it.