Redux
is a widely opinionated tool for state management. Although it's not exclusively made for react
but it's praised by a lot of react developers.
Redux
uses a big javascript object called the state
tree to store and preserve the global state of the application.
Which we can access via dispatching actions to the reducer.
Reducer is a special function and in a higher-level language, I can say reducer is something that takes the original part of the state that it needs to work on and the action that you want it to do and gives away the result. Like a black box.
Now this is a very beautiful concept but you can not do something like this.
const reducer = async (state = initialState, action) => {
let { users } = state;
if (action.type === LOAD_USER) {
const userData = await loadUser(...);
users.push(userData)
return { ...state, loading: true }
}
}
To fetch and update state tree with async data, the traditional way is to use applyMiddleWare or some 3rd partly library like redux-thunk. But I won't be using that.
To bypass all the fuss we'll use a little trick.
Since react takes care of all the visual state of the application we just have to make sure that after our async function completes it should somehow tell redux that "yo! buddy I have done the thing that you asked for" and then redux can simply add/modify that information inside the global state tree.
And here is how we can do that.
Loading Async Data in reducer
This is a multi-step process
- First we will pass an action to the reducer which will make an async call.
- Then on the callback of that async action we will set up another dispatch that will be called after that async action completes.
- In the meanwhile we can return that state of the tree with an isLoading label set to true from the original action.
- The on-completion action will just return the state with the modified values and the loading label to false.
et voila.
Example Application.
In this application, I have used the same concept to load users asynchronously from jsonplaceholder. api.
You can check out the Github repo from here 👇
REDUX for async tasks
You can manage async data in redux via two methods
- Via 3rd party liberary like redux thunk
- Unhealthy but simple way : Kind of a ruse
I am not using the second way because it adds additional compelexiy of the middle ware.
Main concept behind 2nd method
Since state of the application changes everytime the state tree changes. I can dispatch onCompletion
action in the callbackasyncLoading
action which is inside the reducer
.
const reducer = (state = initialState, action) => {
let { users } = state;
if (action.type === DONE) {
console.log('-updated-')
return { ...state, loading: false}
} else if (action.type === LOAD_USER) {
loadUser(...).then((user) => {
users.push(user)
…Live Demo
Thanks for reading.
Hope this may have added a little value, however small that may be.
Resources
Cover Image:
https://medium.com/swlh/handling-asynchronous-actions-with-redux-thunk-86b8d8e0b83e
This article by Robin Kim follows the redux-thunk middleware approach so it's my advice to check it out.
Thanks again! Have a lovely day.
Top comments (0)