Created
June 6, 2019 14:29
-
-
Save mauricedb/4f4071bfbf395a50ed22e919da520cb7 to your computer and use it in GitHub Desktop.
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 React from 'react'; | |
import ListGroup from 'react-bootstrap/ListGroup'; | |
import { url } from '../../shared/jokes-api'; | |
import Loading from '../../shared/loading'; | |
function reducer(state, action) { | |
switch (action.type) { | |
case 'loaded': | |
return { ...state, loading: false, jokes: action.payload }; | |
case 'error-loading': | |
return { ...state, loading: false, error: action.payload }; | |
default: | |
return state; | |
} | |
} | |
function useThunkedReducer(reducer, initialState) { | |
const [state, dispatch] = React.useReducer(reducer, initialState); | |
const thunkedDispatch = React.useCallback( | |
action => { | |
if (typeof action === 'function') { | |
action(thunkedDispatch, state); | |
} else { | |
dispatch(action); | |
} | |
}, | |
[dispatch, state] | |
); | |
return [state, thunkedDispatch]; | |
} | |
async function fetchData(dispatch, state) { | |
if (state.jokes) return; | |
try { | |
const rsp = await fetch(url); | |
if (rsp.ok) { | |
const data = await rsp.json(); | |
dispatch({ type: 'loaded', payload: data.value }); | |
} else { | |
throw new Error(rsp.statusText); | |
} | |
} catch (e) { | |
dispatch({ type: 'error-loading', payload: e }); | |
} | |
} | |
function useJokes(url) { | |
const [state, dispatch] = useThunkedReducer(reducer, { | |
jokes: null, | |
error: null, | |
loading: true | |
}); | |
React.useEffect(() => { | |
dispatch(fetchData); | |
}); | |
return state; | |
} | |
const FetchWithCustomHooks = () => { | |
const { loading, error, jokes } = useJokes(url); | |
if (loading) { | |
return <Loading />; | |
} | |
if (error) { | |
return <div>{error && error.message}</div>; | |
} | |
return ( | |
<ListGroup> | |
{jokes.map(item => ( | |
<ListGroup.Item key={item.id}>{item.joke}</ListGroup.Item> | |
))} | |
</ListGroup> | |
); | |
}; | |
export default FetchWithCustomHooks; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment