Skip to content

Instantly share code, notes, and snippets.

@mauricedb
Created June 6, 2019 14:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mauricedb/4f4071bfbf395a50ed22e919da520cb7 to your computer and use it in GitHub Desktop.
Save mauricedb/4f4071bfbf395a50ed22e919da520cb7 to your computer and use it in GitHub Desktop.
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