Skip to content

Instantly share code, notes, and snippets.

@jayendrasharan
Last active December 6, 2019 20:08
Show Gist options
  • Save jayendrasharan/981f2931dd52836fd92b960e736c05bf to your computer and use it in GitHub Desktop.
Save jayendrasharan/981f2931dd52836fd92b960e736c05bf to your computer and use it in GitHub Desktop.
Simulating an async action using thunk
/**
* In redux environment, when we deal with async calls, we cannot use the dispatch to dispatch a
* a plain action. An action creator in redux is a pure function which returns
* an object with action type (must have) and necessary payload.
* See following example.
*/
// actions.js
// action creator to dispatch an add todo action
// with given payload
export const addTodo = (payload) => ({
type: 'ADD_A_TODO',
payload
});
// reducer.js
const initialState = {
todos: [],
otherProps: {}
};
function todo (state = initialState, action) {
switch (action.type) {
case 'ADD_A_TODO':
return {
...state,
todos: [...state.todos, action.payload]
}
default:
return state;
}
}
// some-container.js
dispatch(addTodo({
id: '21234',
title: 'Create a gist',
description: 'Create a gist about simulating async action',
completed: true,
createdOn: '12/07/2019',
pendingOn: '12/08/2019',
}));
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ASYNC
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/**
* The above example uses a 'addTodo' action creator which is a pure function
* and returns an object, with the type attribute added with given payload.
* To simulate the asyn functionality without having an backend API server, we
* can take help of setTimeout.
*/
// while creating the store, use thunk as a middleware.
// action.js
const apiCallStarted = () => ({
type: 'API_CALL_STARTED'
});
const apiCallCompleted = () => ({
type: 'API_CALL_COMPLETED'
});
export const asyncAddTodo = (payload) => {
// since thunk has been added as a middleware, this action creator now
// can return a function with dispatch. Thunk will inject redux's dispatch.
return (dispatch) => {
// first dispatch a pure action creator to inform async call has started.
dispatch(apiCallStarted());
// wait for 500 milliseconds before dispatching addTodo action
setTimeout(() => {
dispatch(addTodo(payload));
dispatch(apiCallCompleted));
}, 500);
}
}
// some-container.js
dispatch(asyncAddTodo({
id: '21234',
title: 'Create a gist',
description: 'Create a gist about simulating async action',
completed: true,
createdOn: '12/07/2019',
pendingOn: '12/08/2019',
}));
/**
* The reducer to handle 'ADD_A_TODO' case will remain same. However, you can add other
* actions types to handle loading in the UI.
*/
// reducer.js
const initialState = {
todos: [],
apiInProgress: false,
otherProps: {}
};
function todo (state = initialState, action) {
switch (action.type) {
case 'API_CALL_STARTED':
return {
...state,
apiInProgress: true,
};
case 'API_CALL_COMPLETED':
return {
...state,
apiInProgress: false,
};
case 'ADD_A_TODO':
return {
...state,
todos: [...state.todos, action.payload]
}
default:
return state;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment