When to use Global State (Zustand) vs Local State in React ?

Here are the key principles to help you decide which variables belong in a Zustand store:

Put in Zustand Store:

  1. Shared State
  • Data needed by multiple components
  • State that needs to persist across route changes
  • User authentication/session info
const useAuthStore = create((set) => ({
  user: null,
  isAuthenticated: false,
  login: (userData) => set({ user: userData, isAuthenticated: true }),
  logout: () => set({ user: null, isAuthenticated: false })
}));
  1. Global App Settings
  • Theme preferences
  • Language/localization settings
  • Feature flags
const useSettingsStore = create((set) => ({
  theme: 'light',
  language: 'en',
  toggleTheme: () => set((state) => ({ 
    theme: state.theme === 'light' ? 'dark' : 'light' 
  }))
}));
  1. Cached Data
  • API responses that need to be reused
  • Data that's expensive to fetch
const useDataStore = create((set) => ({
  products: [],
  lastFetched: null,
  setProducts: (products) => set({ 
    products, 
    lastFetched: new Date() 
  })
}));

Keep in Local State (useState):

  1. UI State
  • Form input values
  • Loading states
  • Modal open/close states
const [isLoading, setIsLoading] = useState(false);
const [formData, setFormData] = useState({});
  1. Component-Specific State
  • Temporary data that only affects one component
  • State that resets when component unmounts
const [isExpanded, setIsExpanded] = useState(false);
const [selectedItem, setSelectedItem] = useState(null);
  1. Ephemeral State
  • Search input values
  • Filter selections that don't need to persist
const [searchQuery, setSearchQuery] = useState('');
const [activeFilter, setActiveFilter] = useState('all');

Example Decision Process:

// ❌ Don't put in Zustand - Component specific
const [isMenuOpen, setIsMenuOpen] = useState(false);

// ✅ Put in Zustand - Needed across components
const useCartStore = create((set) => ({
  items: [],
  addItem: (item) => set((state) => ({ 
    items: [...state.items, item] 
  }))
}));

// ❌ Don't put in Zustand - Temporary form state
const [formValues, setFormValues] = useState({
  name: '',
  email: ''
});

// ✅ Put in Zustand - User preferences that persist
const usePreferencesStore = create((set) => ({
  notifications: true,
  emailFrequency: 'daily',
  updatePreferences: (prefs) => set(prefs)
}));

Key Questions to Ask:

  1. Does this state need to be shared between components?
  2. Does this state need to persist across page refreshes/navigation?
  3. Would multiple components benefit from accessing this state?
  4. Is this state temporary or permanent?
  5. Is the state specific to a single component's UI?

If you answer "yes" to questions 1-3, it's likely a good candidate for Zustand. If you answer "yes" to questions 4-5, it probably belongs in local state.

Remember: Don't over-globalize state. Start with local state and move to Zustand only when you have a clear need for global state management.