State management for your React applicaitons.

Vlad Antsitovich
5 min readFeb 10, 2022

In my job as a front-end developer, I saw a lot of Redux code, and to be honest, sometimes it makes me sick. Why? The problem is how we use Redux. Let’s figure out what is wrong with it.

ALERT: This article is not about getting rid of Redux. It’s just my thoughts and how I think we should use this tool.

Let’s figure out what is a good state manager library should provide for us?

  • Normalized data: we don’t want to duplicate our data in global store.
  • Data transforms consistently: for example, you want to make sure the transformation of data is quite consistent, so that whenever you pass your input that’s exactly what you’re getting as an output.
  • Visualize global state: its helps to debug what is going on.

Can we use only build-in solutions to manage aplication state?

React Context API and Redux are not the same, yeah we can use both for managing a global state, but it depends on your app. I saw projects when people started implementing their own Redux based on React Context.

For example, we know that when data in React Context changes it triggers a re-render for all components that use this context, so we need to implement our own useSelector hook and etc. features that Redux already can provide us.

Check out Redux Origins: The History Behind the Popular Library and Why React Context is Not a “State Management” Tool (and Why It Doesn’t Replace Redux)

So if React Context is not enough for us we stick to Redux or any other state management library cuz they provide us optimization. But wait, we have a problem with it. Let’s figure out why?

Redux is simple. We don’t need to think about data architecture. At least in the beginning. And problems start when we work with data from a server.

Let’s look a Redux flow.

Redux Flow

Redux gives us one store. It’s a tool to store and change state. State is data in our application and this state we can change only with set of operations (actions). And all it works synchronously.

Synchrony is not enough for us our applications should work with data from server.

And to implement asynchronous actions we need to use middlewares like Redux Saga, Redux Thunk or some thing like this. And that’s when the problems start!

To understand these problems we need to figure out what types of states our application can have.

Client State vs. Server State

Client (UI) State it’s any information that is relevant to your Web browser session, for example, a user can change theme (light or dark).

Server State it’s data that’s stored on the server but needed to display on the client, for example blog posts or user information that is stored in database.

“Server cache is not the same as UI state, and should be handled differently.”

Here is a grate article about it by Kent C. Dodds My State Management Mistake

Also check out Managing React Application State Management

Why we should not use Redux for Server State (Cache)?

As I mention before Redux is simple. So we also add tools like Redux Saga to work with asynchronous, when we want to get data from the server and render it.

Yeah, it gives us to load get data from a server, but we also need to work and manage this data. Redux and async middlewares don’t give us any tools to do this.

And we need to write a lot of boilerplate code for this. I mean a lot.

We need to handle errors and loading state, allow callbacks for onSuccess and onFail, manage pagination, prefetching, duplication requests, retry on error.

Maybe from beginning, you can say you don’t need all of this, but it’s until your application will grow.

Let’s look at one example. Imagine we have two or more components that use the same data, all these components are not on the same page, the question is where we can do action to get this data?

In only one specific component? Hm, at some point we may discover the problem of the hidden component dependency. It means if we will remove this component or never use it our data will never load. But this data need for second component that still uses in our application.

On the root of applicaiton? But what if we will not visit these pages where this data uses?

In each component? Seems right cuz all these components become independent and we don’t need to carry about if this data was loaded before or not, we load this data in a component. The next problem is what if we already loaded this data? How we can handle this? So we check if we have the data in state and if it’s not we will fetch it. A lot of work, doesn’t it? And we need to implement it in each application.

Lucky for us we are not the first who gets the same problem. And smart people already provided their solution for this.

Redux Toolkit can help us to reduce boilerplate code. I’m very impressed by Redux Toolkit and would like to use it in my next projects, but sometimes it’s not enough. To learn how to use Redux Toolkit check out Learn Modern Redux by using Redux Toolkit! (with Mark Erikson) and Modern Redux with Redux Toolkit

React Query, SWR, Apollo Client, RTK Query all these tools come to help us. Here you can find a comparison.

What are React Query, SWR, Apollo Client, RTK Query?

These are libraries to manage server state for your React Application to maintain a cache of server data on the client. So it’s managing the data and it’s your job to indicate when you want to update the cache with new data from the server.

Also check out:

--

--