In the frontend world, while developing a single page application (SPA), we add lots of complexities for a better user experience. Since SPA is all about performance and responsive UI updates, we need to have a single source of truth of our server responses and cached data, as well as locally created data that has not yet been persisted to the server.
Managing this ever-changing state is hard. We perform optimistic updates, meaning changing different parts of UI even before the server has accepted the change is another level of complexity. We then also have to think what if the server rejects the change ? We will have to revert the changes that we did. Now imagine this for a series of asynchronous events. To handle all these complexties, we need to have a single source of truth which our UI components have to obey. We call this the state of our application.
What does Redux solve ?
Redux is used mostly for application state management. Redux maintains the state of an entire application in a single immutable state tree (object), which can't be changed directly. When something changes, a new object is created using action creators and reducers and then the new store pushes this change to the react components which need the update. The problem solved by Redux is the containment of all state changes, rather than having a large collection of small state changes scattered in your code in individual React components.
By localizing state changes into one single store, it becomes easy not only to share data between different React components but also to mange the state. Redux attempts to make state mutations predictable by imposing certain restrictions on how and when updates can happen. From Redux docs, there are three principles that needs to be followed.
- Single source of truth
- State is read-only
- Changes are made with pure functions
These principles make sure that you dont mutate the state of your application. The concept of Redux is really good but probably we can have something more slim than Redux without the heavy learning curve using the concepts that React provides.
How does redux work ?
The concept of redux is simple. We define the initial state of the application in Redux. Depending on various user actions or behaviour of our application, we dispatch actions. Actions contains information about the type of the action along with data. It then reaches reducers (pure functions) which is responsible to update store without mutating the store. Once the store has updated, the new updates are then received by the appropriate React components. Lets see an example.
There is a todo list where you can add a todo item and remove a todo item. When the user writes a new todo and clicks add, a click event is triggered and then the below workflow proceeds.
Click Event => Action dispatched => Reducer => Store updates => UI updates
Do we need Redux ?
There is no one answer to this question. There is a problem and redux solves it. However, with the new concepts of React and the constantly evolving API, we can take advantage of React's concepts to build our own Redux like library which can be much much slimmer than Redux by cutting down the additional features which we probably don't need. After working with Redux for almost 3 years, I am slowly getting dettached from Redux in favour of other alternatives which are easy to understand and can be tuned as per our requirements.
Based on the problems we discussed above, we will build our own Redux library using React's context API and hooks. Since this post is exceeding the average metal capacity to stack so much information in our brains, I will write it in my next blog post.