I'm following the Zustand slice pattern:
import { create, StateCreator } from 'zustand'
interface BearSlice {
bears: number
addBear: () => void
eatFish: () => void
}
interface FishSlice {
fishes: number
addFish: () => void
}
interface SharedSlice {
addBoth: () => void
getBoth: () => void
}
const createBearSlice: StateCreator<BearSlice & FishSlice, [], [], BearSlice> = (set) => ({
bears: 0,
addBear: () => set((state) => ({ bears: state.bears + 1 })),
eatFish: () => set((state) => ({ fishes: state.fishes - 1 })),
})
const createFishSlice: StateCreator<BearSlice & FishSlice, [], [], FishSlice> = (set) => ({
fishes: 0,
addFish: () => set((state) => ({ fishes: state.fishes + 1 })),
})
const createSharedSlice: StateCreator<BearSlice & FishSlice, [], [], SharedSlice> = (set, get) => ({
addBoth: () => {
// you can reuse previous methods
get().addBear()
get().addFish()
// or do them from scratch
// set((state) => ({ bears: state.bears + 1, fishes: state.fishes + 1 })
},
getBoth: () => get().bears + get().fishes,
})
const useBoundStore = create<BearSlice & FishSlice & SharedSlice>()((...a) => ({
...createBearSlice(...a),
...createFishSlice(...a),
...createSharedSlice(...a),
}))
I would like to get the slice root propery in front of each slice like so:
const useBoundStore = create<{ bearSlice: BearSlice; fishSlice: FishSlice, sharedSlice: SharedSlice }>()((...a) => ({
bearSlice: createBearSlice(...a),
fishSlice: createFishSlice(...a),
sharedSlice: createSharedSlice(...a),
}))
I could insert the root property inside the slice, but that would require me to update all sets such as:
set((state) => ({ bears: state.bears + 1 }))
to
set((state) => ({ bearSlice: { ...state.bearSlice, bears: state.bearSlice.bears + 1 }} ))
and that is impossible considering my real code base.
Any suggestions?