I have a simple store for a set of strings, and methods to add and remove strings. However, when persisted the names are converted to JSON objects when saved and not converted back to Sets when read from local storage. The same will happen for Map objects.
I was able to convert to Sets previously using serialize
and deserialize
, but those methods are now deprecated.
import AsyncStorage from "@react-native-async-storage/async-storage"
import { create } from "zustand"
import { createJSONStorage, persist } from "zustand/middleware"
interface Store {
names: Set<string>
addName: (name: string) => void
removeName: (name: string) => void
}
export const useStore = create<Store>()(
persist(
(set) => {
return {
names: new Set(),
addName: (name: string) => {
set((state) => {
const names = new Set(state.names)
names.add(name)
return { names }
})
},
removeName: (name: string) => {
set((state) => {
const names = new Set(state.names)
names.delete(name)
return { names }
})
}
}
},
{
name: "domain-storage",
storage: createJSONStorage(() => AsyncStorage),
}
)
)
You can now use Zustand’s storage
prop to serialize and deserialize maps and sets:
storage: {
getItem: (name) => {
const str = localStorage.getItem(name)
return {
state: {
...JSON.parse(str).state,
transactions: new Map(JSON.parse(str).state.transactions),
},
}
},
setItem: (name, newValue) => {
const str = JSON.stringify({
state: {
...newValue.state,
transactions: Array.from(newValue.state.transactions.entries()),
},
})
localStorage.setItem(name, str)
},
removeItem: (name) => localStorage.removeItem(name),
},
See the Zustand documentation here, which describes the storage
prop as the replacement for the deprecated serialize
and deserialize
: