1.8 KiB
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
functionandoptions. - Use the
React.useState()hook to initialize thevalue,errorandloadingstate variables. - Use the
React.useEffect()hook to callrun()method and update the state variables accordingly ifoptions.autoRunset to true. - Use the
runfunction to manually triggerhandlerfunction. - Return an object containting the
value,errorandisLoadingstate variables andrunfunction.
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>
);
};