Last active
October 28, 2020 22:28
-
-
Save brunopk/48adec0adeb769ea5579162a8738ab3b to your computer and use it in GitHub Desktop.
Generic custom hook for querying services and update components asynchronously
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {useReducer, useEffect} from 'react'; | |
const A_FETCH_SET_PARAM = 'FETCH_SET_PARAM'; | |
const A_FETCH_INIT = 'FETCH_INIT'; | |
const A_FETCH_SUCCESS = 'FETCH_SUCCESS'; | |
const A_FETCH_FAILURE = 'FETCH_FAILURE'; | |
const A_FETCH_FAILURE_RESET = 'FETCH_FAILURE_RESET'; | |
const INITIAL_STATE = { | |
isLoading: false, | |
isError: false, | |
param: null, | |
result: null, | |
}; | |
/** | |
* Query service asynchronously | |
* @param {Function} service service | |
* @returns {Array} Returns an array with [result, isLoading, isError, fetch, reset] | |
* - Initial values: [null, false, false, Function, Function] | |
* - fetch: (params) -> {} function to trigger the hook | |
* - reset: () -> null function to reset the hook in case of error (isError == true) | |
*/ | |
function useFetchService(service) { | |
const [state, dispatch] = useReducer((prevState, action) => { | |
switch (action.type) { | |
case A_FETCH_SUCCESS: | |
return { | |
...prevState, | |
isLoading: false, | |
result: action.data, | |
}; | |
case A_FETCH_FAILURE: | |
return { | |
...prevState, | |
isError: true, | |
isLoading: false, | |
}; | |
case A_FETCH_INIT: | |
return { | |
...prevState, | |
isLoading: true, | |
isError: false, | |
}; | |
case A_FETCH_SET_PARAM: | |
return { | |
...prevState, | |
param: action.param, | |
}; | |
default: | |
case A_FETCH_FAILURE_RESET: | |
return INITIAL_STATE; | |
} | |
}, INITIAL_STATE); | |
useEffect(() => { | |
const fetchData = async () => { | |
try { | |
dispatch({type: A_FETCH_INIT}); | |
let res = await service(state.param); | |
dispatch({type: A_FETCH_SUCCESS, data: res}); | |
} catch (error) { | |
console.error(error); | |
dispatch({type: A_FETCH_FAILURE}); | |
} | |
} | |
if (state.param !== null) { | |
fetchData(); | |
} | |
}, [state.param, service]); | |
return [ | |
state.result, | |
state.isLoading, | |
state.isError, | |
(param) => dispatch({type: A_FETCH_SET_PARAM, param}), | |
() => dispatch({type: A_FETCH_FAILURE_RESET}), | |
]; | |
} | |
export {useFetchService}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment