Files
30-seconds-of-code/snippets/UseAsync.md
2020-01-09 22:05:12 +05:30

1.8 KiB

title, tags
title tags
useAsync hooks,state,effect,intermediate

A hook that handles asynchronous calls.

  • Create a custom hook that takes a handler function and options.
  • Use the React.useState() hook to initialize the value, error and loading state variables.
  • Use the React.useEffect() hook to call run() method and update the state variables accordingly if options.autoRun set to true.
  • Use the run function to manually trigger handler function.
  • Return an object containting the value, error and isLoading state variables and run function.
const useAsync = (fn, options = {}) => {
  const [value, setValue] = React.useState(null);
  const [error, setError] = React.useState(null);
  const [isLoading, setIsLoading] = React.useState(false);

  const autoRun = options.autoRun || false;

  const run = async (args = null) => {
    try {
      setIsLoading(true);
      const value = await fn(args);
      setIsLoading(false);
      setError(null);
      setValue(value);
    } catch (error) {
      setIsLoading(false);
      setError(error);
      setValue(null);
    }
  };

  React.useEffect(() => {
    if (autoRun) {
      run();
    }
  }, [autoRun]);

  return {
    value,
    error,
    isLoading,
    run,
  };
};
const App = () => {
  const handleSubmit = args => {
    // args { foo: bar }
    const url = "https://jsonplaceholder.typicode.com/todos";
    return fetch(url).then(response => response.json());
  };

  const submission = useAsync(handleSubmit, { autoRun: false });

  return (
    <div>
      <button
        onClick={() => submission.run({ foo: "bar" })}
        disabled={submission.isLoading}
      >
        {submission.isLoading ? "Loading..." : "click me"}
      </button>
      <pre>{JSON.stringify(submission.value, null, 2)}</pre>
    </div>
  );
};