Skip to content
albarmox logo
albarmox
software engineer · frontend
Back to BlogsMay 25, 2026

State Management Strategy: When to Use Local, Global, and Server State

Not all state is equal. Learn the clear boundaries between local, global, and server state — and how to pick the right tool for each without over-engineering.

State Management Strategy: When to Use Local, Global, and Server State

State management is one of the most over-engineered aspects of frontend development. Teams reach for Redux on day one because it's "industry standard" — and end up with hundreds of lines of boilerplate for a form that only needs `useState`. The key insight is that not all state is the same. There are three fundamentally different kinds of state, and each has its own best tool. ## Local State Local state is owned by a single component and doesn't need to be shared. This is the vast majority of state in most applications. ```tsx const [isOpen, setIsOpen] = useState(false); const [selectedUser, setSelectedUser] = useState<User | null>(null); const [searchQuery, setSearchQuery] = useState(""); ``` If state never leaves one component, keep it with `useState`. Don't put it in a global store — that's premature complexity. ## Global State Global state is shared across multiple pages or features that don't have a direct parent-child relationship. Classic examples: - Current authenticated user/session - Theme preference (dark/light) - Sidebar open/closed - User permissions - Global notification queue For this, Zustand is an excellent choice. It's minimal, hook-based, and doesn't require the setup overhead of Redux: ```ts import { create } from "zustand"; type AuthStore = { user: User | null; setUser: (user: User | null) => void; }; export const useAuthStore = create<AuthStore>((set) => ({ user: null, setUser: (user) => set({ user }), })); ``` ## Server State Server state is data that lives on a server — a list of users, a product catalog, a report. Many developers make the mistake of fetching this data and storing it in their global Redux or Zustand store. This creates a secondary cache that's difficult to keep synchronized with the real data. The right tool is React Query (TanStack Query), which manages the full lifecycle of server data: fetching, caching, background revalidation, and error handling. ```ts const { data: users, isLoading } = useQuery({ queryKey: ["users"], queryFn: getUsers, staleTime: 1000 * 60 * 5, // consider fresh for 5 minutes }); ``` ## The Decision Rule Before reaching for a state management solution, ask: 1. Is this used by only one component? → `useState` 2. Is this data from the server? → React Query 3. Is this shared across many unrelated components? → Zustand/Context Following this hierarchy prevents the two most common mistakes: storing server data in a global store (duplication), and storing local state in a global store (over-engineering).

Localoka project preview