🧸
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
  • Persistence
  • Rehydration
  • <PersistGate />
  • useRehydrate()

Was this helpful?

  1. Guides

Persisting & rehydrating data

PreviousCreating & using a storeNextUsing middlewares

Last updated 3 years ago

Was this helpful?

Previous versions of zfy used to rely on a custom persistence solution. Fortunately, zustand added built-in support for this feature in . Therefore: zfy simply employs zustand's and tries to offer an easier API to use.

Refer to the to read the full API reference.

Persistence

Data is persisted on a store to store basis. In order to make a store persist its data, you need to provide the persist option to 3rd argument and specify which storage solution you'd like to use:

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

import type { StoresDataType } from '../types'

export const initialState: StoresDataType['user'] = {
  id: '',
  likes: 0,
}

export default createStore<StoresDataType['user']>('user', initialState, {
  persist: { getStorage: () => AsyncStorage },
})

This means that you can have stores using different storage solutions depending on your use case (LocalStorage, Cookies, IndexedDB, etc).

You need to make sure that your storage solution provides agetItem(), asetItem() and aremoveItem()(only needed for zustand v4).

If it does not, of course, you can always provide it yourself:

import { MMKV } from 'react-native-mmkv'
import { createStore } from '@colorfy-software/zfy'

import type { StoresDataType } from '../types'

export const initialState: StoresDataType['user'] = {
  id: '',
  likes: 0,
}

export const storage = new MMKV({ id: 'user' })

export default createStore<StoresDataType['user']>('user', initialState, {
  persist: {
    getStorage: () => ({
      getItem: (name) => storage.getString(name) ?? null,
      setItem: (name, value) => storage.set(name, value),
      removeItem: (name) => storage.delete(name),
    }),
  },
})

Rehydration

Similarly to the persistence solution, zfy directly uses zustand's rehydration under the hood and simply exposes it via a different (hopefully simpler) API.

<PersistGate />

This component expects an array of stores and will take care of displaying its children only when all the stores will have been rehydrated. You can as well provide a loader if needed:

src/App.tsx
import { SafeAreaView, Text } from 'react-native'
import { PersistGate } from '@colorfy-software/zfy'

import appStore from './stores/app-store'
import userStore from './stores/user-store'

const Loader = () => (
  <SafeAreaView>
    <Text>⏳ Loading...</Text>
  </SafeAreaView>
)

export default function App() {
  return (
    <PersistGate stores={[appStore, userStore]} loader={<Loader />}>
      <MyApp />
    </PersistGate>
  )
}

Note that if you add stores in thestores array that do not have thepersist middleware enabled,<PersistGate/>(as well as useRehydrate())will automatically skip them.

useRehydrate()

src/App.tsx
import { useEffect } from 'react'
import { SafeAreaView, Text } from 'react-native'
import { useRehydrate } from '@colorfy-software/zfy'

import appStore from './stores/app-store'
import userStore from './stores/user-store'

const Loader = () => (
  <SafeAreaView>
    <Text>Loading...</Text>
  </SafeAreaView>
)

export default function App() {
  const isRehydrated = useRehydrate([appStore, userStore])

  useEffect(() => {
    if (isRehydrated) {
      // 📍 Trigger side effect upon rehydration?
    }
  }, [isRehydrated])

  return isRehydrated ? <Loader /> : <MyApp />
}

If you want to rehydrate/check the rehydration status of a given store directly, please refer to the corresponding section of the zustand's documentation:

If you want to look into how to bundle stores by type of storage solutions used, for instance, refer to the guide.

From there you're all set. Just use getState().update() to update your store as covered in the guide and your data will be persisted.

Usually, when it comes to rehydration, you might want to hide all (or part) of your app while the necessary stores are rehydrating. zfy provides 2 solutions out of the box to do so: a component - - and a React Hook, .

If <PersistGate /> doesn't fit your need, you can have finer control over what happens via :

🤓
Handling multiple stores
<PersistGate/>
useRehydrate()
useRehydrate()
v3.1.4
persist middleware
createStore()
CreateStoreOptionsType.persist
Creating & using a store
https://github.com/pmndrs/zustand/wiki/Persisting-the-store's-data#rehydrate