JSFiddle - React, Tailwind, and code Playground
by Valentin Sarychev
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="root"></div>
JavaScript
function useAsync(fn) {
const [value, setValue] = React.useState(null);
const [error, setError] = React.useState(null);
const [loading, setLoading] = React.useState(true);
React.useEffect(() => {
let cancelled = false;
setValue(null);
setError(null);
setLoading(true);
fn().then(result => { // TODO: add retries
if (!cancelled) setValue(result);
}).catch(error => {
if (!cancelled) setError(error);
}).then(() => {
if (!cancelled) setLoading(false);
});
return () => {
cancelled = true;
}
}, [fn]);
return React.useMemo(() => ({value, loading, error}), [value, loading, error]);
}
const f = () => Promise.resolve(1);
function Component() {
const result = useAsync(f);
console.log(result);
return null;
}
ReactDOM.render(React.createElement(Component), document.querySelector("#root"));