When writing redux-thunk
functions, known as thunks there is allot of boilerplate that could be easily abstracted away. For example in most of our async API calls we are doing the following, without any side-effects:
export const LOGIN_REQUEST = 'my-app/auth/LOGIN_REQUEST';
export const LOGIN_RECIEVE = 'my-app/auth/LOGIN_RECIEVE';
export const LOGIN_FAILURE = 'my-app/auth/LOGIN_FAILURE';
// ... reducer code here
export function login(loginHandle, password) {
return (dispatch, getState, api) => {
dispatch({ type: LOGIN_REQUEST });
api.post('/auth/login', { loginHandle, password }).then(
response => dispatch({ type: LOGIN_RECIEVE, response }),
error => dispatch({ type: LOGIN_FAILURE, error })
);
};
}
Easy! Although as this covers at least 70% of our requests I'm sure there is an elegant way to abstract away allot of the above code to something like this (pseudo code):
export function login(loginHandle, password) {
return (dispatch, getState, api) => api('POST', LOGIN_REQUEST, '/auth/login', { loginHandle, password });
}
When we need to check the state and other side effects we can go back to a proper thunk. Although for most cases... we could cut this down?
Any elegant ideas?
Redux Thunk lets you inject a custom argument since 2.1.0.
const api = createApi() // you would write this function
const store = createStore(
reducer,
applyMiddleware(thunk.withExtraArgument(api))
)
// your action creator:
function fetchUser(id) {
return (dispatch, getState, api) => {
// you can use api here
}
}
In the future, if your thunks get too complicated, you might want to consider redux-saga or redux-observable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With