How Requestly improved react state management using redux toolkit.

Rohan
Requestly Engineering
3 min readJan 7, 2023

Initially, we use react context + useReducer combination for state management. Here react context does not manage the state but, it helps in avoiding prop drilling. All the global state was kept in a single context.

Problem: Whenever any state updates in this global context, all the components consuming this context using useContext were forced to re-render.
So because of this, a state which was updating very frequently was causing re-render for all the components which were consuming the context but were not dependent on that frequently updating state. There was no proper way to keep track of why and what global state was updated.

Let's understand the problem in more detail.

Whenever the value x in the react context gets updated the Child1 component will be forced to re-render to receive fresh values of the context. But with this Child2 component will also be forced to re-render even though it's not using the value x.

The below table represents the number of renders for some sets of components.

This is expected, and it's okay for small applications, but in our case, the UI is complex and large, and there were lots of components that were undergoing unnecessary re-renders.

Solution 1: Using multiple contexts
Split the state using multiple context providers, by careful analysis ie having a separate context for very frequently updating state.
Also to use React.memo for avoiding unnecessary re-renders, but also doesn’t want to overuse them. And React.memo will also fail to prevent re-renders caused by the updation of context values, for more on this read.

Solution 2: Using redux-toolkit
So we decided to use redux-toolkit, which is like a wrapper around redux, which directly means less boilerplate code. With redux-toolkit, we only need to worry about the state and the reducers, and the rest it will take care of, yes it will automatically create actions and action-creators for us.
Redux toolkit uses reducer and slice names for creating the action types. Also for writing updation logic, we don't need to care about purity or immutability, since redux-toolkit uses immer internally, so it will take care of it.

The below table shows the final comparison in component renders between context and redux.

Advantages of using redux-toolkit:
1. Components consuming the global state using useSelector hook inside a component will only cause a re-render of the component when that specific global state (ie state which we retrieved using useSelector hook) is updated.

2. We can use Redux Devtools extension, to keep track of why and what global state was updated.

Redux devtool

This provides more information about the state updation in the app compared to the context. We can backtrack on how a specific state has been updated over time, which user action triggered the state update, which indirectly provides a better way for debugging.

Thanks for reading.

Requestly

--

--