Skip to content

Instantly share code, notes, and snippets.

@cassidoo
Last active February 24, 2023 00:27
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cassidoo/ecaac347694aeb6f906464fbc8ef68c7 to your computer and use it in GitHub Desktop.
Save cassidoo/ecaac347694aeb6f906464fbc8ef68c7 to your computer and use it in GitHub Desktop.
export default function usePromise(api) {
const [state, dispatch] = useReducer(
(state, action) => {
switch (action.type) {
case 'LOADING':
return { ...state, loading: true }
case 'RESOLVED':
return { ...state, loading: false, response: action.response, error: null }
case 'ERROR':
return { ...state, loading: false, response: null, error: action.error }
default:
return state
}
},
{
loading: false,
response: null,
error: null,
}
)
useEffect(() => {
let isCurrent = true
dispatch({ type: 'LOADING' })
api()
.then(response => {
if (!isCurrent) return
dispatch({ type: 'RESOLVED', response })
})
.catch(error => {
dispatch({ type: 'ERROR', error })
})
return () => (isCurrent = false)
}, [api])
return [state.response, state.loading, state.error]
}
/////////////////
// Example usage
/////////////////
const example = usePromise(
useCallback(
() => fetch(...),
[whatever-dependency-you-want]
)
)
// Here's an example of if you had a `getProduct` fetching API
const products = usePromise(useCallback(() => api.getProduct(productId), [productId]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment