Last active
December 6, 2019 20:08
-
-
Save jayendrasharan/981f2931dd52836fd92b960e736c05bf to your computer and use it in GitHub Desktop.
Simulating an async action using thunk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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