React Redux Tutorial: A Beginner’s Guide to Redux
When applications are small, it’s fine to manage state within a component. As your application becomes more complex, however, you may end up with bloated components full of various methods for managing and updating state. This is a problem because you will quickly run into a scenario where multiple components need access to the same state.
By moving components’ state to an application-wide single source of truth, Redux helps create applications that behave consistently and scale more easily. In addition, you don’t update the state directly using Redux. Instead, you send state change requests through reducers using actions, allowing for serializing state changes and creating a time-travelling debugging option where you can track state changes over time.
Use Redux With or Without React (& Vice Versa)
The reason why React and Redux work so well together, and are paired so often, is because Redux makes working with React much more manageable. Together, React Redux simplifies and standardizes state management in complex applications.
That said, you might not need Redux. Dan Abramov, co-author of Redux, has written about the tradeoffs of using Redux in your applications. Sometimes, it introduces unnecessary complexity and abstraction into your application. It shouldn’t be a standard library you use anytime you build a React app.
React already offers state management within components themselves, but each component has its own state. The real reason why you would want to go through the trouble of adding Redux is to separate “What happened?” from “What do we do about it?” at the application level.
You should think about using Redux when multiple components in React need to be able to access the same state, but they don’t have a parent-child relationship. Or, if it starts to get complicated passing down state to multiple components using props.
Keeping States Out of Components
It’s worth mentioning here that using local state is fine in many applications. There’s no inherent need to create an abstraction layer for managing state. Everything depends on context and weighing the tradeoffs of using React Redux.
That said, separating state from the component has the potential to make applications faster. Removing state from components untangles our code. Again, for a simple app this might not be an issue, but for complicated apps where multiple components interact and need to share state information, having a single source of truth quickly becomes important.
Updating State with React Redux
When we want to change the state, we can no longer use setState() like we would with React. Instead, we have to call action generators that communicate with a reducer that manages all the changes. This is called dispatching, or the act of sending a payload of information to our store. When we dispatch an action, we’re sending an object that describes what happened.
This makes things slightly more awkward as a developer writing code. There are libraries to help with this like Immutable.js however keeping things simple to start is advisable. Additionally, since the actions we dispatched are be serialized, it makes it possible for us to track all changes to state, travel through time for debugging, implement undo/redo functionality, and coordinate state across components. The Redux framework does not allow another action to be dispatched until the previous one has completed.
How it Works with React
Adding a redux store to a React application does nothing until you connect it with your components. This is where the power comes in and the coding pattern differs. Instead of using components with internal state you now use a built in function called connect that comes out of the react-redux package. Once a component is connected it will get new props every time the part of the state changes that the component cares about. When the props change, the component renders again just as you would expect.
A big advantage to moving state out of components is it allows us to write basic components that are purely functions of their props with with little internal logic. This promotes the use of react functional components for even simpler code.
Advantages of React Redux
We’ve already seen some of the advantages of using Redux with React. Since we can now implement logging, debugging and replaying now becomes a lot easier. We can travel to specific points in time to see what the state of all components was any given moment. Once the developer learns to update state by dispatching actions, instead of setState(), the rest of this functionality falls into place without the need for further buy-in from the development team.
The major advantage is that Redux scales to large and complex apps with little overhead. Any component in the app can look to a single source of truth for state.
React Redux is an Investment
Using Redux isn’t without its costs. It adds a layer of abstraction to the development process that comes with a learning curve and more time up front on development. However, Redux’s costs are more of an investment as they’ll pay off in maintainability and scalability for complex apps over time.
Perhaps the best advice for whether your should learn and use React Redux comes from Dan Abramov again, “Flux libraries are like glasses: you’ll know when you need them.” They can be powerful and useful. Redux is definitely worth learning once you’ve got a solid grasp on React. However, Redux shouldn’t be a go to solution for every project. Be judicious in how you decide to use React Redux, and it’ll pay off.