Skip to content

Instantly share code, notes, and snippets.

@AlexanderProd
Created January 17, 2021 11:43
Show Gist options
  • Save AlexanderProd/588bc51609eec5f2191f2c7cf82cef27 to your computer and use it in GitHub Desktop.
Save AlexanderProd/588bc51609eec5f2191f2c7cf82cef27 to your computer and use it in GitHub Desktop.
useAsync.js
import { useReducer, useRef, useEffect, useCallback } from 'react';
function reducer(state, action) {
switch (action.type) {
case 'PENDING':
return { ...state, status: 'pending' };
case 'SUCCESS':
return { ...state, status: 'success', value: action.value };
case 'ERROR':
return { ...state, status: 'error', error: action.error };
default:
throw new Error();
}
}
export const useAsync = (asyncFunction, immediate = false) => {
const [state, dispatch] = useReducer(reducer, {
status: 'idle',
value: null,
error: null,
});
const isAlive = useRef(true);
useEffect(() => {
return () => (isAlive.current = false);
}, []);
const execute = useCallback(
(params = []) => {
dispatch({ type: 'PENDING' });
return asyncFunction(...params)
.then(response => {
if (isAlive.current) {
dispatch({ type: 'SUCCESS', response });
}
return 'success';
})
.catch(error => {
if (isAlive.current) {
dispatch({ type: 'ERROR', error });
}
return 'error';
});
},
[asyncFunction]
);
useEffect(() => {
if (immediate) {
execute();
}
}, [execute, immediate]);
return { execute, ...state };
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment