Back to Blog
May 1, 2026
2 min readUpdated: May 12, 2026

Handling State in Modern React Applications

Do you have a question or doubt about something?

Scroll down to the bottom to ask your question, and I or anyone else will respond!

Handling State in Modern React Applications

Choose the right tool for the job. Here's how .

The Decision Matrix

ScenarioBest ToolWhy
Local UI state (modal open/closed)useStateSimple, built-in
Form stateuseReducer + ContextComplex validation
Server cache (API data)React Query / TanStack QueryAutomatic refetching, caching
Global app state (user, theme)Zustand or Context + useReducerLightweight, simple
Complex enterprise stateRedux ToolkitPredictable, DevTools, large ecosystem
URL state (filters, pagination)Next.js router / React RouterSource of truth in URL

Implementation Examples

Zustand (recommended for most apps)

import { create } from 'zustand';

interface CounterState {
  count: number;
  loading: boolean;
  increment: () => void;
  decrement: () => void;
  incrementByAmount: (amount: number) => void;
}

export const useCounterStore = create<CounterState>()((set) =&gt; ({
  count: 0,
  loading: false,
  increment: () =&gt; set((state) =&gt; ({ count: state.count + 1 })),
  decrement: () =&gt; set((state) =&gt; ({ count: state.count - 1 })),
  incrementByAmount: (amount) =&gt; set((state) =&gt; ({ count: state.count + amount })),
}));

// Use in component
function Counter() {
  const { count, increment, decrement } = useCounterStore();
  // Only re-renders when 'count' changes due to selector
}

Redux Toolkit (for complex apps)

import { createSlice, configureStore } from '@reduxjs/toolkit';

const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment: (state) =&gt; { state.value += 1 },
    decrement: (state) =&gt; { state.value -= 1 }
  }
});

// Create typed hooks
export const useAppDispatch = () =&gt; useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

Performance Rule

> "Atlassian removed their barrel files and saw a 75% reduction in average build times, a 30% improvement in IDE highlighting speed, and an 88% drop in unit tests executed per PR"

Key insight: How you organize your state management code affects your entire development experience.

Step-by-Step: Choose Your State Management

  1. Start with local state (useState, useReducer)
  2. Lift state up when 2+ components need it
  3. Add Context when 3+ levels deep
  4. Add Zustand/Redux when Context causes performance issues
  5. Add React Query when you have server data

Resources

LibraryDocsWhen to Use
Zustanddocs.pmnd.rs/zustandMost new apps
Redux Toolkitredux-toolkit.js.orgEnterprise, existing Redux
Jotaijotai.orgAtomic state
React Querytanstack.com/queryServer state

Was this helpful?

Discussion

0

Do you have a question or any doubt?

Ask here and I or anyone else will respond!

Loading comments...
2B

By 2BigDev

Full-Stack Engineer