You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Redux is an open-source JavaScript library commonly used with React for managing the state of web applications. It provides a centralized store to manage the entire application's state, making state management predictable and efficient, especially in large-scale applications with complex data flow.
When to use Redux
Not long after its release, Redux became one of the hottest topics of debate in the frontend world.
Redux allows you to manage your app’s state in a single place and keep changes in your app more predictable and traceable, making it easier to understand the changes happening in your app. But all of these benefits come with a set of challenges. Some developers argue that Redux introduces unnecessary boilerplate, potentially complicating what are otherwise simple tasks. However, this depends on the architectural decisions of the project.
So, when should you use Redux? One simple answer to this question is that you will organically realize for yourself when you need Redux. If you’re unsure about whether you need it, you probably don’t. This usually happens when your app grows to a scale where managing app state becomes a hassle and you start looking for ways to make it simplify it.
Using Redux with React
As we mentioned earlier, Redux is a standalone library that can be used with different JavaScript frameworks including Angular, Inferno, Vue, Preact, React, etc. However, Redux is most frequently used with React.
This is because React only allows for a uni-directional flow of data. That means data cannot be sent from a child to a parent; it has to flow downward from the parent to the child. This thought model works very well with Redux where we cannot directly modify the state. Instead, we dispatch actions that intend to change the state, and then separately, we observe the resulting state changes.
State management with Redux
State management is essentially a way to facilitate the communication and sharing of data across components. It creates a tangible data structure to represent the state of your app that you can read from and write to. That way, you can see otherwise invisible states while you’re working with them.
Most libraries, such as React and Angular, are built with a way for components to internally manage their state without the need for an external library or tool. This works well for applications with few components, but as an application grows larger, managing states shared across components becomes a hassle.
In an app where data is shared among components, it might be confusing to actually know where a state should live. Ideally, the data in a component should live in just one component, so sharing data among sibling components becomes difficult.
For example, to share data among siblings in React, a state has to live in the parent component. A method for updating this state is provided by the parent component and passed as props to these sibling components.
Here’s a simple example of a login component in React. The input of the login component affects what is displayed by its sibling component, the status component:
Remember, this data is not needed by the parent component, but because its children need to share data, it has to provide a state.
Now imagine what happens when a state has to be shared between components that are far apart in the component tree. Basically, the state will have to be lifted up to the nearest parent component and upwards until it gets to the closest common ancestor of both components that need the state, and then it is passed down. This makes the state difficult to maintain and less predictable.
It’s clear that state management gets messy as the app gets more complex. This is why you need a state management tool like Redux to more easily maintain these states. Now, let’s take a look at Redux concepts before considering its benefits.
How Redux works
The way Redux works is simple. There is a central store that holds the entire state of the application. Each component can access the stored state without having to send down props from one component to another.
There are three core components in Redux — actions, store, and reducers. Let’s briefly discuss what each of them does. This is important because they help you understand the benefits of Redux and how it can be used.
We’ll be implementing a similar example to the login component above but this time in Redux.
💡 store refers to the object that holds the application data shared between components.
Redux actions
Redux actions are events. They are the only way you can send data from your application to your Redux store. The data can be from user interactions, API calls, or even form submissions.
Actions are plain JavaScript objects that must have:
A type property to indicate the type of action to be carried out
A payload object that contains the information that should be used to change the state
Actions are created via an action creator, which is a function that returns an action. Actions are executed using the dispatch() method, which sends the action to the store:
Here’s an example of an action:
{type: "INCREMENT",payload: {incrementBy: 5,}}Andhereisanexampleofanactioncreator.Itisjustahelperfunctionthatreturns the action:
constgetIncrementAction=(numberToIncrement)=>{return{type: "INCREMENT",payload: {incrementBy: numberToIncrement,}}}
Redux reducers
Reducers are pure functions that take the current state of an application, perform an action, and return a new state. The reducer handles how the state (application data) will change in response to an action:
💡 A pure function is a function that will always return the same value if given the same parameters, i.e., the function depends on only the parameters and no external data.
Reducers are based on the reduce function in JavaScript, where a single value is calculated from multiple values after a callback function has been carried out.
Here is an example of how reducers work in Redux:
constCounterReducer=(state=initialState,action)=>{switch(action.type){// This reducer handles any action with type "LOGIN"case"INCREMENT":
returnstate+action.incrementBy ? action.incrementBy : 1default:
returnstate;}};
Hence, if the initial state was 12, after the action to increment it by five gets dispatched and processed, we get the new value of the state, i.e., 17.
💡 Reducers take the previous state of the app and return a new state based on the action passed to it. As pure functions, they do not change the data in the object passed to them or perform any side effect in the application. Given the same object, they should always produce the same result.
Redux store
The store is a “container” (really, a JavaScript object) that holds the application state, and the only way the state can change is through actions dispatched to the store. Redux allows individual components to connect to the store.
It is highly recommended to keep only one store in any Redux application. You can access the stored state, update the state, and register or unregister listeners via helper methods. Basically, the components get to update the store via actions and then subscribe to the changes to the store so they know when to re-render:
Redux toolkit
Redux is a great utility for state management in React. But, as we mentioned before, it can introduce a lot of boilerplate into your application due to the verbosity of its API. Because of this, it is recommended to use the Redux Toolkit while using Redux with React. Let’s look at a few benefits that this provides.
Setting up a store with Redux toolkit
While setting up a store with pure Redux can be quite cumbersome, with Redux Toolkit, it is a single call to the configureStore function. This is how we can set up a store that has a counterReducer slice in it:
Redux Toolkit also provides us with utilities to generate actions. In Redux, actions are just normal objects with a type and a payload field. The createAction utility from Redux Toolkit returns us a function. We can call that function with any object and it will get dispatched as the payload for that particular action:
The reducer in Redux is a normal, pure function that takes care of the various possible values of state using the switch case syntax. But that means several things need to be taken care of — most importantly, keeping the state immutable.
Redux Toolkit provides the createReducer utility, which internally uses immer. This allows us to freely mutate the state, and it will internally be converted to an immutable version. This is how a reducer defined with Redux Toolkit would look like:
Notice how easy that makes the task of playing with the state. The difference is more evident when the state is more complex with several nested objects. In the scenario without Redux Toolkit, we have to be careful to keep all the operations immutable but the equivalent code with Toolkit is much more simplified:
// a case without toolkit, notice the .map to create a new statecase'TOGGLE_TODO': {const{ index }=action.payloadreturnstate.map((todo,i)=>{if(i!==index)returntodoreturn{
...todo,completed: !todo.completed,}})}// a case with toolkit, notice the mutation which is taken care internally.addCase('TOGGLE_TODO',(state,action)=>{consttodo=state[action.payload.index]// "mutate" the object by overwriting a fieldtodo.completed=!todo.completed})
With that in place, let’s now move to learning about what Redux middleware are and how they can further simplify the overall experience.
Redux middleware
Redux allows developers to intercept all actions dispatched from components before they are passed to the reducer function. This interception is done via middleware, which are functions that call the next method received in an argument after processing the current action.
Here’s what a simple middleware looks like:
functionsimpleMiddleware({ getState, dispatch }){returnfunction(next){returnfunction(action){// processingconstnextAction=next(action);// read the next stateconststate=getState();// return the next action or you can dispatch any other actionreturnnextAction;}}}
This might look overwhelming, but in most cases, you won’t need to create your own middleware because the Redux community has already made many of them available. If you feel middleware is required, you will appreciate its capacity to enable great work with the best abstraction.
conclusion
Redux is a powerful JavaScript library commonly used with React for managing the state of web applications. It provides a centralized store to manage the entire application's state, following a predictable and efficient pattern. With concepts like actions, reducers, and a unidirectional data flow, Redux simplifies state management by enforcing a clear separation of concerns and providing a single source of truth for the application's state. Redux offers benefits such as predictability, scalability, and powerful debugging capabilities through tools like Redux DevTools. While Redux may introduce some initial setup and boilerplate code, it remains a popular choice for state management in React applications, especially for projects requiring complex data flow or scalability. Overall, Redux is a valuable tool for building maintainable, scalable, and predictable React applications.
The text was updated successfully, but these errors were encountered:
Redux
what is redux ?
Redux is an open-source JavaScript library commonly used with React for managing the state of web applications. It provides a centralized store to manage the entire application's state, making state management predictable and efficient, especially in large-scale applications with complex data flow.
When to use Redux
Not long after its release, Redux became one of the hottest topics of debate in the frontend world.
Redux allows you to manage your app’s state in a single place and keep changes in your app more predictable and traceable, making it easier to understand the changes happening in your app. But all of these benefits come with a set of challenges. Some developers argue that Redux introduces unnecessary boilerplate, potentially complicating what are otherwise simple tasks. However, this depends on the architectural decisions of the project.
So, when should you use Redux? One simple answer to this question is that you will organically realize for yourself when you need Redux. If you’re unsure about whether you need it, you probably don’t. This usually happens when your app grows to a scale where managing app state becomes a hassle and you start looking for ways to make it simplify it.
Using Redux with React
As we mentioned earlier, Redux is a standalone library that can be used with different JavaScript frameworks including Angular, Inferno, Vue, Preact, React, etc. However, Redux is most frequently used with React.
This is because React only allows for a uni-directional flow of data. That means data cannot be sent from a child to a parent; it has to flow downward from the parent to the child. This thought model works very well with Redux where we cannot directly modify the state. Instead, we dispatch actions that intend to change the state, and then separately, we observe the resulting state changes.
State management with Redux
State management is essentially a way to facilitate the communication and sharing of data across components. It creates a tangible data structure to represent the state of your app that you can read from and write to. That way, you can see otherwise invisible states while you’re working with them.
Most libraries, such as React and Angular, are built with a way for components to internally manage their state without the need for an external library or tool. This works well for applications with few components, but as an application grows larger, managing states shared across components becomes a hassle.
In an app where data is shared among components, it might be confusing to actually know where a state should live. Ideally, the data in a component should live in just one component, so sharing data among sibling components becomes difficult.
For example, to share data among siblings in React, a state has to live in the parent component. A method for updating this state is provided by the parent component and passed as props to these sibling components.
Here’s a simple example of a login component in React. The input of the login component affects what is displayed by its sibling component, the status component:
Now imagine what happens when a state has to be shared between components that are far apart in the component tree. Basically, the state will have to be lifted up to the nearest parent component and upwards until it gets to the closest common ancestor of both components that need the state, and then it is passed down. This makes the state difficult to maintain and less predictable.
It’s clear that state management gets messy as the app gets more complex. This is why you need a state management tool like Redux to more easily maintain these states. Now, let’s take a look at Redux concepts before considering its benefits.
How Redux works
The way Redux works is simple. There is a central store that holds the entire state of the application. Each component can access the stored state without having to send down props from one component to another.
There are three core components in Redux — actions, store, and reducers. Let’s briefly discuss what each of them does. This is important because they help you understand the benefits of Redux and how it can be used.
We’ll be implementing a similar example to the login component above but this time in Redux.
Redux actions
Redux actions are events. They are the only way you can send data from your application to your Redux store. The data can be from user interactions, API calls, or even form submissions.
Actions are plain JavaScript objects that must have:
A type property to indicate the type of action to be carried out
A payload object that contains the information that should be used to change the state
Actions are created via an action creator, which is a function that returns an action. Actions are executed using the dispatch() method, which sends the action to the store:
Here’s an example of an action:
Redux reducers
Reducers are pure functions that take the current state of an application, perform an action, and return a new state. The reducer handles how the state (application data) will change in response to an action:
Reducers are based on the reduce function in JavaScript, where a single value is calculated from multiple values after a callback function has been carried out.
Here is an example of how reducers work in Redux:
Hence, if the initial state was 12, after the action to increment it by five gets dispatched and processed, we get the new value of the state, i.e., 17.
Redux store
The store is a “container” (really, a JavaScript object) that holds the application state, and the only way the state can change is through actions dispatched to the store. Redux allows individual components to connect to the store.
It is highly recommended to keep only one store in any Redux application. You can access the stored state, update the state, and register or unregister listeners via helper methods. Basically, the components get to update the store via actions and then subscribe to the changes to the store so they know when to re-render:
Redux toolkit
Redux is a great utility for state management in React. But, as we mentioned before, it can introduce a lot of boilerplate into your application due to the verbosity of its API. Because of this, it is recommended to use the Redux Toolkit while using Redux with React. Let’s look at a few benefits that this provides.
Setting up a store with Redux toolkit
While setting up a store with pure Redux can be quite cumbersome, with Redux Toolkit, it is a single call to the configureStore function. This is how we can set up a store that has a counterReducer slice in it:
Creating an action using Redux Toolkit
Redux Toolkit also provides us with utilities to generate actions. In Redux, actions are just normal objects with a type and a payload field. The createAction utility from Redux Toolkit returns us a function. We can call that function with any object and it will get dispatched as the payload for that particular action:
Creating the reducer with Redux Toolkit
The reducer in Redux is a normal, pure function that takes care of the various possible values of state using the switch case syntax. But that means several things need to be taken care of — most importantly, keeping the state immutable.
Redux Toolkit provides the createReducer utility, which internally uses immer. This allows us to freely mutate the state, and it will internally be converted to an immutable version. This is how a reducer defined with Redux Toolkit would look like:
Notice how easy that makes the task of playing with the state. The difference is more evident when the state is more complex with several nested objects. In the scenario without Redux Toolkit, we have to be careful to keep all the operations immutable but the equivalent code with Toolkit is much more simplified:
With that in place, let’s now move to learning about what Redux middleware are and how they can further simplify the overall experience.
Redux middleware
Redux allows developers to intercept all actions dispatched from components before they are passed to the reducer function. This interception is done via middleware, which are functions that call the next method received in an argument after processing the current action.
Here’s what a simple middleware looks like:
This might look overwhelming, but in most cases, you won’t need to create your own middleware because the Redux community has already made many of them available. If you feel middleware is required, you will appreciate its capacity to enable great work with the best abstraction.
conclusion
Redux is a powerful JavaScript library commonly used with React for managing the state of web applications. It provides a centralized store to manage the entire application's state, following a predictable and efficient pattern. With concepts like actions, reducers, and a unidirectional data flow, Redux simplifies state management by enforcing a clear separation of concerns and providing a single source of truth for the application's state. Redux offers benefits such as predictability, scalability, and powerful debugging capabilities through tools like Redux DevTools. While Redux may introduce some initial setup and boilerplate code, it remains a popular choice for state management in React applications, especially for projects requiring complex data flow or scalability. Overall, Redux is a valuable tool for building maintainable, scalable, and predictable React applications.
The text was updated successfully, but these errors were encountered: