Skip to content
D
Documentation

Compose a store from slices

how-to
2 min readUpdated

Split a growing store into feature-focused state creators, then combine them into one store your React components can use. Build the combined hook with create and type each slice creator with StateCreator.

When to use slices

Use slices when keeping every feature's state and actions in one large creator makes the store harder to maintain. A slice is a creator for part of the store's state; combining slices does not create separate stores for your components. Your components use the one combined hook and can select state from any slice.

Define, combine, and render the slices

  1. Give each feature a state type and creator. Spread the returned slice objects into one typed store, then render a component that selects from both slices. The example starts with the profile name Jordan and compact mode off. Its buttons rename the profile and toggle the preference.
tsx
import { create, type StateCreator } from 'zustand'

interface ProfileSlice {
  profileName: string
  renameProfile: (name: string) => void
}

interface PreferencesSlice {
  compactMode: boolean
  toggleCompactMode: () => void
}

type SettingsStore = ProfileSlice & PreferencesSlice

const createProfileSlice: StateCreator<
  SettingsStore,
  [],
  [],
  ProfileSlice
> = (set) => ({
  profileName: 'Jordan',
  renameProfile: (name) => set({ profileName: name }),
})

const createPreferencesSlice: StateCreator<
  SettingsStore,
  [],
  [],
  PreferencesSlice
> = (set) => ({
  compactMode: false,
  toggleCompactMode: () =>
    set((state) => ({ compactMode: !state.compactMode })),
})

export const useSettingsStore = create<SettingsStore>()((...args) => ({
  ...createProfileSlice(...args),
  ...createPreferencesSlice(...args),
}))

export function App() {
  const profileName = useSettingsStore((state) => state.profileName)
  const renameProfile = useSettingsStore((state) => state.renameProfile)
  const compactMode = useSettingsStore((state) => state.compactMode)
  const toggleCompactMode = useSettingsStore(
    (state) => state.toggleCompactMode,
  )

  return (
    <main>
      <h1>Settings for {profileName}</h1>
      <p>Compact mode: {compactMode ? 'on' : 'off'}</p>
      <button onClick={() => renameProfile('Casey')}>Rename to Casey</button>
      <button onClick={toggleCompactMode}>Toggle compact mode</button>
    </main>
  )
}
Look at the initial profile name, compact-mode value, and two controls rendered from the combined store.

The first StateCreator type is the full store state; the fourth is the slice returned by that creator. In this example, both creators use empty mutator tuples. The spreads combine the profile and preference values and actions into one store, so the component can select from either feature. Clicking Rename to Casey changes the heading; clicking Toggle compact mode changes the displayed preference.

What to watch out for

  • Keep each slice creator focused on the state and actions for its feature. When one action needs to update fields from more than one slice, define that action against the combined store state.
  • Apply middleware to the combined store, not inside individual slice creators; applying middleware inside slices can lead to unexpected issues. See Middleware and composition for middleware type arguments.
  • Keep updates immutable. See Update nested state for nested objects and React quick start for why mutating previous state does not notify subscribers.
  • Select primitive values or stable references in components. See Select state efficiently for selectors that create new references.

Was this page helpful?

Compose a store from slices — zustand · GPT-6 Luna