Skip to content

Instantly share code, notes, and snippets.

@christianalfoni
Created April 30, 2021 07:11
Show Gist options
  • Save christianalfoni/aeabf25ab18482d7f153a92aeac0755a to your computer and use it in GitHub Desktop.
Save christianalfoni/aeabf25ab18482d7f153a92aeac0755a to your computer and use it in GitHub Desktop.
const reducer = (context, event) => {
switch (event.type) {
case 'FETCH':
return {
...context,
state: 'fetching',
};
case 'RESOLVE':
return {
state: 'fulfilled',
user: event.data,
};
default:
return context;
}
};
const initialState = { state: 'idle', user: undefined };
const Fetcher = () => {
const [context, dispatch] = useReducer(reducer, initialState);
useEffect(() exec(context, {
fetching: () => {
fetch(`/api/users/${effect.user}`)
.then(res => res.json())
.then(data => {
dispatch({
type: 'RESOLVE',
data,
});
});
}
})
return (
<button
onClick={() => {
dispatch({ type: 'FETCH', user: 42 });
}}
>
Fetch user
</div>
);
};
const fetchEffectReducer = (state, event, exec) => {
switch (event.type) {
case 'FETCH':
// Capture a named effect to be executed
exec({ type: 'fetchFromAPI', user: event.user });
return {
...state,
status: 'fetching',
};
case 'RESOLVE':
return {
status: 'fulfilled',
user: event.data,
};
default:
return state;
}
};
const initialState = { status: 'idle', user: undefined };
const fetchFromAPIEffect = (_, effect, dispatch) => {
fetch(`/api/users/${effect.user}`)
.then(res => res.json())
.then(data => {
dispatch({
type: 'RESOLVE',
data,
});
});
};
const Fetcher = () => {
const [state, dispatch] = useEffectReducer(fetchEffectReducer, initialState, {
// Specify how effects are implemented
fetchFromAPI: fetchFromAPIEffect,
});
return (
<button
onClick={() => {
dispatch({ type: 'FETCH', user: 42 });
}}
>
Fetch user
</div>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment