🧸
zfy
  • Getting started
  • 🤓Guides
    • Creating & using a store
    • Persisting & rehydrating data
    • Using middlewares
    • Handling multiple stores
    • Type checking with TypeScript
  • 📚API reference
    • Types
      • CreateStoreType
      • CreateStoreConfigType
      • CreateStoreOptionsType
      • StoreType
      • ZfyMiddlewareType
      • InitStoresType
      • InitStoresResetOptionsType
    • createStore
    • initStores
    • PersistGate
    • useRehydrate
  • 🗃️Others
    • Help
    • Contributing
    • Changelog
    • GitHub
Powered by GitBook
On this page
  • Built-in
  • Custom

Was this helpful?

  1. Guides

Using middlewares

PreviousPersisting & rehydrating dataNextHandling multiple stores

Last updated 3 years ago

Was this helpful?

By default, a zustand store only lets you get and set data. As soon as you'll want it to do more (persist data, log updates, subscribe to changes, etc) is when zustand middlewares will come into play. zfy offers 2 types of middleware for that purpose: and .

Built-in

Out of the box, you have access to a , and middlewares. There's not much you'll need to do here as these middlewares can be configured directly in . You can use none, one or all of them at once:

import AsyncStorage from '@react-native-async-storage/async-storage'
import { createStore } from '@colorfy-software/zfy'

const data = { name: 'zfy' }

type StoreDataType = typeof data

const store = createStore<StoreDataType>('store', data, {
  persist: { getStorage: () => AsyncStorage },
  subscribe: true,
  log: true,
})

const listener = (newName, oldName) => console.log({ newName, oldName })

const unsubscribe = store.subscribeWithSelector?.(
  state => state.data.name,
  listener,
  { fireImmediately: true }
)

Custom

import { devtools } from 'zustand/middleware'
import { ZfyMiddlewareType, createStore } from '@colorfy-software/zfy'

const data = { name: 'zfy' }

type StoreDataType = typeof data

const customMiddleware: ZfyMiddlewareType<StoreDataType> =
  (storeName, config) => (set, get, api) =>
    config(
      (args) => {
        // 📍Do anything in your middlware
        set(args)
        console.log(storeName)
      },
      get,
      api
    )

const zustandMiddleware: ZfyMiddlewareType<StoreDataType> = (storeName, config) =>
  devtools((set, get, api) => config(set, get, api), { name: storeName })

const store = createStore('store', data, {
  customMiddlewares: [customMiddleware, zustandMiddleware],
})

This snippet is only provided as an example to show you how to integrate a zustand middleware. You shouldn't rely on devtools as zfy uses Immer instead of Redux-like actions & dispatchers.

Here, in just 3 lines, you've enabled zustand's own persist & subscribeWithSelector middlewares, on top of zfy's middleware.

The middleware will print the store name, previous state, payload data and new state upon each update.

You can refer to zustand's documentation for details about & middlewares.

At some point, your use cases might require more than what the 3 built-in middlewares can offer. It could be that you want to use another of zustand's middleware or even plug in your very own custom middleware. zfy allows you to do so via the option:

You'll notice that zfy's middlewares look a tiny bit different from zustand's. Instead of only config as in the initial function argument, you also receive thestoreName (the one you provided as first argument). This can be very useful if you want to have conditional logic in your middleware based on which store is using it for instance.

🤓
persist
subscribeWithSelector
createStore()
createStore()
built-in
custom
persist
log
subscribe
log
log
customMiddlewares