Understanding redux data flow
When comes into the development in React, Redux is the buzz word attached to it. Why? Because it eases the management of state along with handling the data flow for components. You know in react if we want to pass some value deep into the component tree we should explicitly thread it from the top-most parent which holds that value. Assume a scenario where we want to share some data among two peer components that do not have common properties and for the absolute reason of sharing that data we need to implement a common ancestor for them and lift the state up to make that sharing possible. Doing this each time you want to handle the data flow is tiresome, isn’t it? That’s where redux comes to your rescue.
Redux offers this data sharing of components possible by maintaining one single state in the store. A single source of truth. All the components which want to get state data at some point are subscribed to the store and they will receive the state each time it gets updated. How simple is that compared to having the state in each component and trying to manage the data flow when we want to share those state data between them. Redux does that for us. All we need to do is to connect our components to attach them as subscribers to the state in the store.
Now, as we know how redux benefits for our application, let’s try to understand its flow. First, spare two minutes looking into the flow diagram below.
Now it is time to dig deep into the redux flow.
Redux has five main entities. Action Creators, Dispatching Function, Reducers, State and Store.
When we want to do some change to the value of an element in the DOM we need to call the action creator that is responsible to do that change.
Action creators simply return an action with a type and a payload.
Then that action should be dispatched to the store using the store’s dispatch()
function. But an action creator is a factory that creates action and does not dispatch it. We enable triggering of the dispatch function, by defining mapStateToProps
with bindActionCreators
. Below I have mentioned two possible ways to do that. (Refer the step 5 of my previous article for further reference.)
When you call an action creator, the wrapper function generated from either of these implementations will forward all the arguments and trigger the dispatch() function for you.
Dispatching Function sends an action to the store’s root reducer along with the current state returned by the store, to generate the new state. That is why the actions should be plain objects so that they can be consumed by the reducers.
Root reducer simply takes two arguments, the current state, and the action. After iterating through all existing reducers, the reducer logic for the matching action type will be executed and it will return the new state. Below I have mentioned an example reducer that has only one reducer function.
State gets changed when the reducer returns the new state.
Store identifies the state has changed and gets all the listeners who have subscribed to the state changes. All the listeners have listener functions that are attached when subscribing to the store using the store’s subscribe(listener)
function. This is happening when you define mapStateToProps
via redux connect.
After calling the listener functions, all the components who subscribed to the state will receive the new state and according to the logic we implemented inmapStateToProps
that data will be assigned to the component’s props. When the prop updates happen, this will trigger render()
functions in components, and React DOM will get updated accordingly.
This is how redux flow works.
If you want a reference to set up redux to your existing react application, read my article Integrate redux into your existing react app in 5 steps if you haven’t so far.
Hope you enjoyed this article and your feedback is welcome.
References -