Why, How and When to Use Redux ?
By: Murat Ogulcan Sahin
Tags: JavaScript, Hooks, React, Redux, Functional Programming

React is a very useful library which creates a virtual DOM filled with components that are either function or class objects that we create with vanilla JS. It compares virtual and real DOM then it renders only the particular components. Some components might need to use the data that other components possess and we pass this shared data via props and as you know, props can only be passed to the child component from the parent component with React. So this is a problem.

Why ?

What makes passing props a problem is we might have nested components structure and in this structure some components might not use the props data but just pass it to the child component.

PlanetsContainer component is not using props data. It is only passing its props to its child component

In this example, we see our nested components passing planets array via props. However, the PlanetsContainer component is not using the data, but is passing it to Planets child component. Now think about having an expansive and complex app. Your component tree would be more complicated and you’d end up passing props all over your app. This would cause poor readability and hard maintenance.

Redux steps in and offers a solution. Its says let’s create a store where we can keep the specific data which we keep passing around and it should be accessible from any component. Thus, we don’t need to keep passing props unnecessarily.

In order to understand Redux, you need to establish a couple norms first. These are Provider, Store, State, Dispatch, Action and Reducer.

Provider is just a parent component of our entire app. As you see on line 5, it wraps around our App component. It provides our store to its child components, in this case App.

Store is return value of createStore() method that we get from react-redux package. There should be only 1 store for your app. It can take up to 3 arguments. First one is mandatory and it is our reducer function. Second one is initial state and it is optional which means if you need preloaded data for your app to use before it starts. Third argument is optional as well and it is called enhancer. It is a function that helps you to use third party libraries for your store such as middlewares like ‘thunk’. Middlewares can be implemented when they are passed as arguments in applyMiddleware() . If you need more than one enhancer functions, you have to pass them as arguments in compose() function. So createStore() argument total number stays as 3.

State is our entire app’s state. If you pass initial state to the store that is your state at the beginning. It can be manipulated by dispatching actions. Any component whose ancestor component is App component can access to it and use the data stored inside.

Dispatch is a function which takes an action as argument and first passes the action to the reducer and makes reducer’s return value our redux store state which is accessible to all components.

Action can be object or function that returns an object that reducer can understand. Mandatorily it is has to have a key named type . Conventionally it looks like {type: "FETCH_DATA", payload: fetchedData} . This object becomes our reducer’s second argument.

Reducer is a function we declare. It should be able to understand passed action and change app’s state the way you app needs it to be. It takes 2 arguments, first argument is our current state. Second argument is dispatched action. Usually you operate with switch statement Return value should be the way you need, meaning it can be an array, JS object etc.

Sequentially,

User interaction or app’s logic triggers action

Action is dispatched

Reducer reads the action and returns new state

State is updated

You can think of Redux store as a data charity foundation where some components donate data and some components get the data. This data is held in a JS object as a value and its conventional variable name is ‘state’. Also in the store, there should be an operator that knows how to manage this data flow, which is called reducer. To make a donation you have to dispatch your action. For example dispatch({type: “DONATE”, payload: $1000}). Reducer will receive your action and process it the way we told it to and change our foundation’s state. In this example would add $1000 to the account. If you’d like to know how much money in the charity account, you would access the state and grab the information to use it however you’d like to.

Redux is absolutely useful and its newly introduced hooks makes it easier to implement to our apps. Keep that in mind, hooks can be only used in functional components. However, based on what you’re building, your app might not require implementing Redux. Always remember the main purpose of Redux, which is to avoid unnecessary data traffic that is caused by using props. Because after all, React props might just do the work.