DEV Community

Ntty
Ntty

Posted on

Stop over-engineering your state management

I spent three years of my career adding Redux to every single project I touched. I thought that was what professional developers did. I built complex store architectures, wrote endless boilerplate for simple toggles, and spent hours debugging why a specific action did not trigger a re-render.

Eventually, I realized I was solving problems I did not actually have.

The Redux Trap

When you start a new project, the instinct is to prepare for scale. You think, "What if this app grows to 50 pages? I will need a central place for all my data." This is a classic trap. You end up building a complex system to manage data that only two components actually care about.

Global state is an expensive tool. It adds cognitive load. Every time you want to change a single string, you have to jump between a slice, an action, a reducer, and the component. For most apps, this is a waste of time.

Start with the simplest tool

Most state is not actually global. It is either local or server state.

Local State

If a piece of data is only used by a component and its immediate children, keep it in the component. If you find yourself "prop drilling" (passing data through five layers of components), do not immediately reach for a global store. Try moving the state up to the nearest common ancestor first.

Server State

This is where most developers get confused. They store API responses in a global store. But an API response is not "state" in the traditional sense. It is a cache of data that lives on a server.

Using a dedicated data fetching library handles caching, loading states, and re-fetching automatically. When you move server data out of your global store, you will find that 80 percent of your Redux or Vuex code simply disappears.

When to actually use global state

Global state is for data that truly spans the entire application and changes frequently. Examples include:

  • User authentication status
  • Theme settings (dark vs light mode)
  • A complex shopping cart in a large e-commerce site

Even then, you do not always need a heavy library. The Context API in React or simple reactive stores in Vue and Svelte are usually enough for these use cases.

A practical migration strategy

If you are currently staring at a bloated store, do not rewrite everything overnight. Try this approach instead:

  1. Identify one piece of state in your store.
  2. Ask: "Which components actually use this?"
  3. If it is only one branch of the component tree, move it to a local state or a Context provider wrapping only that branch.
  4. If it is just a cached API response, move it to a fetching hook.

The mental shift

Writing less code is a skill. It is easy to add a library. It is hard to resist adding one. The goal is not to use the most powerful tool, but the one that makes the code easiest to reason about six months from now.

When I stopped treating global state as the default, my development speed increased. I spent less time writing boilerplate and more time building actual features.

Takeaway: Before adding a state management library, try to solve the problem with local state and a good data fetching strategy. If you still feel the pain, only then should you reach for a global store.

Top comments (0)