Understanding redux data flow

Sunnychoudhury
4 min readJan 24, 2020

--

As we know Redux is a predictable state container for JavaScript apps.It helps us write applications that behave consistently, run in different environments (client, server, and native), and are easy to test.

Redux itself is actually a simple library. It’s easy to get lost in the depth when all that’s needed is a dead simple example of the logic process to refer to. Thus, I described this simple summary.

State: A state in Redux is a JavaScript object, where the internal state of the application is stored as its properties, e.g. which user is logged on. After having logged in, the user of your application may navigate to different pages in your application, but you need to remember somehow, who that user is. That piece of information is part of your application’s internal state.

UI: The user interface (UI) is the point of human-computer interaction and communication in a device. This can include display screens, keyboards, a mouse and the appearance of a desktop. It is also the way through which a user interacts with an application or a website. The growing dependence of many businesses on web applications and mobile applications has led many companies to place increased priority on UI in an effort to improve the user’s overall experience.

Actions: Plain object that is returned by a pure function with no side-effects. The action object contains the “type” and any necessary information to update the state. The object is sent to the store using dispatch(), and the store updates the state using the information contained in the action object. Actions describe that something happened.

Redux: A library which holds and updates the entire state of the app in the simplest manner possible while also using the least amount of boilerplate code.

Store: There is only one and it holds the entire state in a single object. Assign it to a variable using createStore(combinedReducer). The store passes two arguments to the reducer — the previous state and the action.

Reducer: A pure function that takes the current state and action, and performs an update on the state. It returns the new state. Typically use a switch statement that reads the action.type and then creates the new state with this action which is still just a plain JavaScript.

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.


export const ADD_USER = ‘ADD_USER’ // action types
export function addUser(user) { return
{
type: ADD_USER,
user // action payload
}
}

Then that action should be dispatched to the store using the store’s dispatch()function. But an action creator is a function that returns 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.


const mapDispatchToProps = (dispatch) => {
return bindActionCreators(this.addUser, dispatch);} export default connect(mapStateToProps, mapDispatchToProps)(User); //or export default connect(mapStateToProps, {addUser} )(User);

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.

import { ADD_USER } from "../actions";let INITIAL_STATE = {
users:[]
}
function userDataReducer(state= INITIAL_STATE, action) {
switch(action.type) {
case ADD_USER:

return {
...state,
users:action.user
default:

return state;
}
}

State get 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 inmapStateToPropsthat 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.

--

--