* Update docs content * Update docs content * Update docs content * Update docs content * Update docs content * WIP * WIP * Update docs content * Update create.md * Update create-with-equality-fn.md * Update create-store.md * Update use-store.md * Update use-store-with-equality-fn.md
6.2 KiB
| title | description | nav |
|---|---|---|
| devtools | How to time-travel debug your store | 205 |
devtools
devtools middleware lets you use Redux DevTools Extension
without Redux. Read more about the benefits of using Redux DevTools for debugging.
const nextStateCreatorFn = devtools(stateCreatorFn, devtoolsOptions)
Types
Signature
devtools<T>(stateCreatorFn: StateCreator<T, [], []>, devtoolsOptions?: DevtoolsOptions): StateCreator<T, [['zustand/devtools', never]], []>
Mutator
['zustand/devtools', never]
Reference
devtools(stateCreatorFn, devtoolsOptions)
Parameters
stateCreatorFn: A function that takessetfunction,getfunction andstoreas arguments. Usually, you will return an object with the methods you want to expose.- optional
devtoolsOptions: An object to defineRedux Devtoolsoptions.- optional
name: A custom identifier for the connection in the Redux DevTools. - optional
enabled: Defaults totruewhen is on development mode, and defaults tofalsewhen is on production mode. Enables or disables the Redux DevTools integration for this store. - optional
anonymousActionType: Defaults toanonymous. A string to use as the action type for anonymous mutations in the Redux DevTools. - optional
store: A custom identifier for the store in the Redux DevTools.
- optional
Returns
devtools returns a state creator function.
Usage
Debugging a store
This example shows you how you can use Redux Devtools to debug a store
import { create, StateCreator } from 'zustand'
type JungleStore = {
bears: number
addBear: () => void
fishes: number
addFish: () => void
}
const useJungleStore = create<JungleStore>()(
devtools((...args) => ({
bears: 0,
addBear: () =>
set((state) => ({ bears: state.bears + 1 }), undefined, 'jungle/addBear'),
fishes: 0,
addFish: () =>
set(
(state) => ({ fishes: state.fishes + 1 }),
undefined,
'jungle/addFish',
),
})),
)
Debugging a Slices pattern based store
This example shows you how you can use Redux Devtools to debug a Slices pattern based store
import { create, StateCreator } from 'zustand'
import { devtools } from 'zustand/middleware/devtools'
type BearSlice = {
bears: number
addBear: () => void
}
type FishSlice = {
fishes: number
addFish: () => void
}
type JungleStore = BearSlice & FishSlice
const createBearSlice: StateCreator<
JungleStore,
[['zustand/devtools', never]],
[],
BearSlice
> = (set) => ({
bears: 0,
addBear: () =>
set(
(state) => ({ bears: state.bears + 1 }),
undefined,
'jungle:bear/addBear',
),
})
const createFishSlice: StateCreator<
JungleStore,
[['zustand/devtools', never]],
[],
FishSlice
> = (set) => ({
fishes: 0,
addFish: () =>
set(
(state) => ({ fishes: state.fishes + 1 }),
undefined,
'jungle:fish/addFish',
),
})
const useJungleStore = create<JungleStore>()(
devtools((...args) => ({
...createBearSlice(...args),
...createFishSlice(...args),
})),
)
Troubleshooting
Only one store is displayed
By default, Redux Devtools only show one store at a time, so in order to see other stores you
need to use store selector and choose a different store.
All action names are labeled as 'anonymous'
If an action type name is not provided, it is defaulted to "anonymous". You can customize this
default value by providing a anonymousActionType parameter:
For instance the next example doesn't have action type name:
import { create, StateCreator } from 'zustand'
import { devtools } from 'zustand/middleware/devtools'
type BearSlice = {
bears: number
addBear: () => void
}
type FishSlice = {
fishes: number
addFish: () => void
}
type JungleStore = BearSlice & FishSlice
const createBearSlice: StateCreator<
JungleStore,
[['zustand/devtools', never]],
[],
BearSlice
> = (set) => ({
bears: 0,
addBear: () => set((state) => ({ bears: state.bears + 1 })),
eatFish: () => set((state) => ({ fishes: state.fishes - 1 })),
})
const createFishSlice: StateCreator<
JungleStore,
[['zustand/devtools', never]],
[],
FishSlice
> = (set) => ({
fishes: 0,
addFish: () => set((state) => ({ fishes: state.fishes + 1 })),
})
const useJungleStore = create<JungleStore>()(
devtools((...args) => ({
...createBearSlice(...args),
...createFishSlice(...args),
})),
)
In order to fix the previous example, we need to provide an action type name as the third parameter.
Additionally, to preserve the default behavior of the replacement logic, the second parameter
should be set to undefined.
Here's the fixed previous example
import { create, StateCreator } from 'zustand'
type BearSlice = {
bears: number
addBear: () => void
}
type FishSlice = {
fishes: number
addFish: () => void
}
type JungleStore = BearSlice & FishSlice
const createBearSlice: StateCreator<
JungleStore,
[['zustand/devtools', never]],
[],
BearSlice
> = (set) => ({
bears: 0,
addBear: () =>
set((state) => ({ bears: state.bears + 1 }), undefined, 'bear/addBear'),
})
const createFishSlice: StateCreator<
JungleStore,
[['zustand/devtools', never]],
[],
FishSlice
> = (set) => ({
fishes: 0,
addFish: () =>
set((state) => ({ fishes: state.fishes + 1 }), undefined, 'fish/addFish'),
})
const useJungleStore = create<JungleStore>()(
devtools((...args) => ({
...createBearSlice(...args),
...createFishSlice(...args),
})),
)
Important
Do not set the second parameter to
trueorfalseunless you want to override the default replacement logic