Thunk in React

What's a Thunk

A function that's returned from a function. Major idea is that code will be executed later.

It can be used with reducer to create side effect, extra functionality for the reducers.

const reducer = (state, action) => {
if (action.type === 'FETCHING') {
return {
characters: [],
loading: true,
error: null,
};
}
if (action.type === 'RESPONSE_COMPLETE') {
return {
characters: action.payload.characters,
loading: false,
error: null,
};
}
if (action.type === 'ERROR') {
return {
characters: [],
loading: false,
error: action.payload.error,
};
}
return state;
};
const useThunkReducer = (reducer, initialState) => {
const [state, dispatch] = useReducer(reducer, intialState);
// As long as the dispatch is the same, the enhancedDispatch is the same one.
const enhancedDispatch = React.useCallback(action => {
// Can put a log in here or any additional things
console.log(action);
if (isFunction(action)) {
action(dispatch);
} else {
dispatch(action);
}
}, [dispatch]);
return [state, enhancedDispatch];
}
const initialState = {
error: null,
loading: false,
characters: [],
};
// Can be placed anywhere
const fetchCharacters = (dispatch) => {
dispatch({type: 'LOADING'});
fetch(endpoint)
.then(response => response.json())
.then(response => dispatch({type: 'RESPONSE_COMPLETE', payload: {characters: response.characters}}))
.catch(err => dispatch({ type: 'ERROR', payload: {error}}))
}

In the components:

const [state, dispatch] = useThunkReducer(reducer, initialState);
const { characters } = state;
useEffect(() => {
dispatch(dispatch => {});
}, [dispatch]);
const onClickButton = () => dispatch(fetchCharacters);