Redux is a predictable state container for JavaScript applications. It assists in writing apps that behave consistently, and run in different environments i.e. client, server and native are simple to test.
This blog is an attempt to address the fundamentals of Redux. We shall explore what is redux, and its functions. Before moving on if you are not familiar with ReactJs we suggest you read the article below:
Read this: What is ReactJs: Why use it for your next project?
1. What is Redux?
As mentioned earlier Redux is a predictable state container made for helping developers write JavaScript apps that maintain consistency across client, server, and native components and are easy in testing.
In general, it’s useful as a state management tool with react, you can use it with any other JavaScript framework or library. It’s lightweight at 2KB which also includes dependencies. Thus, you don’t have to think about making your apps’ asset size big.
With Redux, the state of the application is kept in a store and each component can access any given state that it requires from this store.
2. Why use Redux?
Normally, an app consists of its state and that state is a combination of states of its internal components. Let us consider an example of an e-commerce website. An e-commerce website will incorporate various components such as a user profile, cart component, previous section and etc.
For instance, consider the cart component, it displays the number of items in a user’s cart. The state of the cart component will include all the items that the user adds to the cart. It will also comprise the total of those items. At each event the application is up and running, this component has to display the updated number of items in the user’s cart.
Here when a user adds a specific item to the cart, the application has to internally handle the event by adding that item to the cart object. It has to retain the state internally and display to the user the total number of items in the cart in the UI. Likewise, if a user is removing an item from the card the decrease in the number of items should occur internally.
This is handled when the app size is small. But, when the application size is extensive it becomes difficult to control multiple states from components with efficiency. Here is where Redux comes into the picture. Being a state management library, it will store and manage all the application states.
Further, it also provides some crucial APIs that one can use to make changes to the existing state. One can easily fetch the current state using such an API.
3. Principles of Redux
In general, Redux is described using three fundamental principles:
✣ Single source of truth
This makes it simple to create universal applications because the state from your server is serialized and blended into the client with no extra coding effort.
A single state tree makes the debugging or inspecting of the app easier. In addition, it also allows us to continue the apps’ state in development for a quicker development cycle.
✣ State is read-only
The method for changing a state is to emit an action. This is basically an object defining what happened. This makes sure that neither the views nor the network callbacks will ever write directly to the state. Here, there is intent to modify the state. But, as all the changes are centralized and occur in a strict order, there are no precise race conditions to look out for.
Actions are plain objects and are easily logged, serialized, stored, and later replayed for debugging or testing.
✣ Changes using pure functions
To specify how the state tree is altered by actions one writes reducer. Reducers are pure functions that take the prior state and an action and return to the next state.
Normally, you can start with a single reducer. However, as your app grows, you can split it off into smaller reducers that handle specific parts of the state tree. As reducers are just functions, you can control the order in which they are invoked, pass additional data, or even create reusable reducers for common tasks such as pagination.
4. Code Samples:
✣ Action
export const incNumber = (num) => {
return {
type: ‘INCREMENT’,
payload: num
}
}
export const decNumber = () => {
return {
type: ‘DECREMENT’
}
};
Action helps to change the state of the app. This is done by emitting or dispatching an action.
✣ Reducers
In reducers, we use the previous state and an action. Afterward, it’s reduced and returned to a single entity which gives us a new instance of the state.
const initialState = 0;
const changeTheNumber = (state = initialState, action) => {
switch (action.type) {
case “INCREMENT”: return state + 1;
case “DECREMENT”: return state – 1;
default: return state;
}
}
export default changeTheNumber;
Thus, when an action is dispatched all reducers start operating. Each reducer filters out the action using a switch case on the action type. In the above code, you can observe reducer changeTheNumber. This reducer is accepting two parameters i.e. state and action. It is important to note that state is the default parameter that accepts an initial state.
On click event, we have dispatched an action with type INCREMENT and called reducer changeTheNumber which takes the initial state and actions with the parameters.
The action type is switched on and then whichever case matches with the dispatched action type makes the essential update and returns the latest new update.
✣ Store
import { createStore } from “redux”;
import reducersfrom “./reducers/index”;
const store = createStore(reducers, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());
export default store;
✣ Combining Reducers
import changeTheNumber from “./updown”;
import { combineReducers } from “redux”;
const reducers = combineReducers(
{
// myNumber:changeTheNumber
changeTheNumber
}
);
✣ Dispatch Increment and Decrement
import React from ‘react’
import “./App.css”;
import {incNumber} from “./actions”;
import {decNumber} from “./actions”;
import { useSelector, useDispatch } from “react-redux”;
const App = () => {
// it alternative to the useContext hooks in react / consumer from context API
const changeTheNumber = useSelector(state => state.changeTheNumber);
const dispatch = useDispatch();
return (
<>
<div className=“main-div”>
<div class=“container”>
<h1>Increment/Decrement counter</h1>
<h4>using React and Redux</h4>
<div class=“quantity”>
<a class=“quantity__minus” title=“Decrement” onClick={() => dispatch(decNumber())}><span>–</span></a>
<input name=“quantity” type=“text” class=“quantity__input” value={changeTheNumber} />
<a class=“quantity__plus” title=“Increment” onClick={() => dispatch(incNumber())}><span>+</span></a>
</div>
</div>
</div>
</>
)
}
export default App
You may also like: TypeScript vs JavaScript: Detailed Comparison
5. Benefits of using Redux
We saw why we should use Redux, here are some perks that will help build the case on why one should use it.
✣ Performance
In general, developers assume that keeping the app’s state global state would reduce its performance. However, this is not the case. React Redux implements various performance optimizations internally so that your own connected component only re-renders only when necessary.
✣ Ease of testing
It is simple to test Redux apps since functions are utilized to modify the state of pure functions.
✣ State persistence
You can continue some of the app’s state to local storage and restore it after a refresh.
✣ Server-side Rendering
Redux is also useful in server-side rendering. You can manage the initial render of the app by sending the state of an app to the server along with its response to the server request. The necessary components are then rendered in HTML and sent to the clients.
✣ Maintainability
In general, Redux is easy to maintain as it is strict on how the code must be arranged. This makes it easy for someone with knowledge of Redux to understand the structure of any Redux application.
✣ Easy Debugging
Debugging an application in Redux is simple. The coding errors, network errors, and other forms of bugs that may arise are easily understood by logging actions and states. However, if the app is big debugging may take more time.
6. Why is Redux suitable with React?
Redux is a standalone library that is useful with numerous JS frameworks such as Angular, Vue, Inferno, and so on. But, nowadays it is often used with React. The reason is simple. React is designed with the concept of states and lifecycles. The state also cannot be altered directly, it is done through the function i.e. setState. This makes it easy for developers to apply concepts of Redux as they both share the same understanding and behavior of a state object.
In fact, Redux is brought in for state management because of the increasing complexity of an application.
Final thoughts on Redux
With the working concepts and benefits, it’s obvious that Redux helps you in better app development. But, this doesn’t imply that you go on using the tool in every app you make, some apps may function better without using Redux.
Overall, Webbybutter suggests you use this concept if your project mandates a state management tool.