From 0fbbc72a1ff57d146ef3b0efca2f11f3e337d8e8 Mon Sep 17 00:00:00 2001 From: zhanggy Date: Mon, 26 May 2025 13:50:43 +0800 Subject: [PATCH 1/3] docs: add custom-middleware.md --- docs/middlewares/custom-middleware.md | 33 +++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 docs/middlewares/custom-middleware.md diff --git a/docs/middlewares/custom-middleware.md b/docs/middlewares/custom-middleware.md new file mode 100644 index 0000000000..502726026b --- /dev/null +++ b/docs/middlewares/custom-middleware.md @@ -0,0 +1,33 @@ +--- +title: custom middleware +description: How to create a custom middleware +nav: 211 +--- + +# custom middleware + +You can make your own `middleware`. + +```js +// Logs will be output every time the state changes +const log = (config) => (set, get, api) => + config( + (...args) => { + console.log(' applying', args) + set(...args) + console.log(' new state', get()) + }, + get, + api + ) + +// zustand +const useBeeStore = create( + log((set) => ({ + bees: false, + setBees: (input) => set({ bees: input }), + })) +) +``` + + From 87460f85cba0f02e1616e04ec0125dc861649db1 Mon Sep 17 00:00:00 2001 From: zhanggy Date: Tue, 27 May 2025 11:14:30 +0800 Subject: [PATCH 2/3] docs: update custom-middleware.md follow the format of api docs: add navigation links & types signature & examples & troubleshooting --- docs/middlewares/custom-middleware.md | 50 ++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/docs/middlewares/custom-middleware.md b/docs/middlewares/custom-middleware.md index 502726026b..a7ec967417 100644 --- a/docs/middlewares/custom-middleware.md +++ b/docs/middlewares/custom-middleware.md @@ -6,11 +6,11 @@ nav: 211 # custom middleware -You can make your own `middleware`. +You can easily create your own `middleware`, just like the `log` below: ```js -// Logs will be output every time the state changes -const log = (config) => (set, get, api) => +// Log when the state changes +const log = (config) => (set, get, store) => config( (...args) => { console.log(' applying', args) @@ -18,16 +18,56 @@ const log = (config) => (set, get, api) => console.log(' new state', get()) }, get, - api + store ) +``` + +- [Types](#types) + - [Signature](#combine-signature) +- [Reference](#reference) +- [Usage](#usage) + - [Log when the state changes](#Log when the state changes) +- [Troubleshooting](#troubleshooting) + +## Types + +### Signature + +```ts +log = (config: StateCreator): StateCreator +``` + +## Reference + +### `log(config)` + +#### Parameters + +- `config`: A function that takes `set` function, `get` function and `store` as arguments. Usually, you will return an object with the methods you want to expose. + +#### Returns + +`log` returns a state creator function. + +## Usage + +### Log when the state changes + +This example shows you how you can create a store and apply log middleware. + +```ts +import { create } from 'zustand' -// zustand const useBeeStore = create( log((set) => ({ bees: false, setBees: (input) => set({ bees: input }), })) ) + +const setBees = useBeeStore((state) => state.setBees) ``` +## Troubleshooting +TBD From af696349a3dd6be166929185746c84359d94e1ca Mon Sep 17 00:00:00 2001 From: zhanggy Date: Fri, 30 May 2025 20:26:02 +0800 Subject: [PATCH 3/3] docs: rewrite & move to guides --- docs/guides/custom-middleware.md | 59 ++++++++++++++++++++++ docs/middlewares/custom-middleware.md | 73 --------------------------- 2 files changed, 59 insertions(+), 73 deletions(-) create mode 100644 docs/guides/custom-middleware.md delete mode 100644 docs/middlewares/custom-middleware.md diff --git a/docs/guides/custom-middleware.md b/docs/guides/custom-middleware.md new file mode 100644 index 0000000000..b3d185b758 --- /dev/null +++ b/docs/guides/custom-middleware.md @@ -0,0 +1,59 @@ +--- +title: How to create a custom middleware +nav: 18 +--- + +In Zustand, middleware is a powerful tool for enhancing the functionality of the store. They allow you to inject custom logic before and after state updates, enabling capabilities such as logging and persistence. Below, we will walk through the creation of a custom middleware by using a logging middleware example. + +## Structure of middleware +Each Zustand middleware follows the same function signature: + +``` javascript +const customMiddleware = (config) => (set, get, store) => { + // custom middleware logic + return config(...) // return the enhanced configuration +} +``` + +## Implementation of `logger` Middleware + +``` javascript +const logger = (config) => (set, get, store) => { + // return the enhanced configuration + return config( + // enhanced set function + (...args) => { + console.log('applying:', args) // logger before state updates + set(...args) // apply set funtion + console.log('new state:', get()) // logger after state updates + }, + get, + store + ) +} +``` + +## Usage +Apply middleware when creating the store: + +```javascript +import create from 'zustand' + +const useStore = create(logger((set) => ({ + count: 0, + increment: () => set((state) => ({ count: state.count + 1 })), + reset: () => set({ count: 0 }) +}))) +``` + +## Middleware Workflow + +1. When the `set` function is called (e.g., `increment()`) +2. The middleware first logs the action parameters: `applying: [ [Function] ]` +3. Executes the actual state update +4. The middleware logs the updated state: `new state: { count: 1, increment: [Function], reset: [Function] }` + +## CodeSandbox Demo + +https://codesandbox.io/p/sandbox/zustand-logger-middleware-skhxhf?file=/src/App.tsx + diff --git a/docs/middlewares/custom-middleware.md b/docs/middlewares/custom-middleware.md deleted file mode 100644 index a7ec967417..0000000000 --- a/docs/middlewares/custom-middleware.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: custom middleware -description: How to create a custom middleware -nav: 211 ---- - -# custom middleware - -You can easily create your own `middleware`, just like the `log` below: - -```js -// Log when the state changes -const log = (config) => (set, get, store) => - config( - (...args) => { - console.log(' applying', args) - set(...args) - console.log(' new state', get()) - }, - get, - store - ) -``` - -- [Types](#types) - - [Signature](#combine-signature) -- [Reference](#reference) -- [Usage](#usage) - - [Log when the state changes](#Log when the state changes) -- [Troubleshooting](#troubleshooting) - -## Types - -### Signature - -```ts -log = (config: StateCreator): StateCreator -``` - -## Reference - -### `log(config)` - -#### Parameters - -- `config`: A function that takes `set` function, `get` function and `store` as arguments. Usually, you will return an object with the methods you want to expose. - -#### Returns - -`log` returns a state creator function. - -## Usage - -### Log when the state changes - -This example shows you how you can create a store and apply log middleware. - -```ts -import { create } from 'zustand' - -const useBeeStore = create( - log((set) => ({ - bees: false, - setBees: (input) => set({ bees: input }), - })) -) - -const setBees = useBeeStore((state) => state.setBees) -``` - -## Troubleshooting - -TBD