--- title: useAsync tags: 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. ```jsx 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, }; }; ``` ```jsx 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 (
{JSON.stringify(submission.value, null, 2)}
); }; ```