Sync local and remote Zustand store in ReactJS

  1. The store
const useStore = create(set => ({
bears: 0,
nutrition: {
breakfast: ["honey"],
diner: ["nuts"]
}
}))
import { useEffect } from "react"
import shallow from "zustand/shallow"
import produce from "immer"
import get from "lodash.get"
import set from "lodash.set"
import { useStore } from "path/to/your/store"/**
* @param {string[]} syncPaths - Paths of the store you want to sync, e.g. ["nutrition.breakfast", "nutrition.diner"]
* @param {Object} newData - Patched data from remote store
* @param {Function} doSendData - Function will be invoked with patched local store data, up to send to remote
*/
const useStoreSync = (syncPaths, newData, doSendData) => {
/**
* This useEffect will be invoked everytime prop syncPaths change.
* It calls doSendData with currently changed state, where key is path of syncedPaths and value is the current state, e.g.:
* {
* "nutrition.breakfast": ["honey"],
* "nutrition.diner": ["nuts"]
* }
*/
useEffect(() => {
const unsubscribes = syncPaths.map(path => {
return useStore.subscribe(
state => get(state, path), changedPath => {
const sendState = { [path]: changedPath }
doSendData(sendState)
}
)
})
return () => unsubscribes.map(unsubscribe => unsubscribe())
}, [syncPaths])
/**
* This useEffect will be invoked everytime remote data (@param newData) changes.
* The local store will be updated with patch Object, which might be:
* {
* "nutrition.breakfast": ["berries", "honey"],
* }
*/
useEffect(() => {
Object.keys(newData).forEach(key => {
useStore.setState(
produce(state => {
set(state, key, newData[key])
}),
)
})
}, [newData])
}
export default useStoreSync

--

--

--

hay I’m Thomas, specialized in crafting unique interfaces & interactions for the browser platform. Meet me on twitter or github: @thomasrutzer

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

React Native Tutorial

SwiftUI: How to make filling wave animation

Journey into GSoC — Part 9

How to Set up a Node.js Express Server for React

Detect React Route Change in Vanilla JavaScript

A Peek Into The LocalStorage world

Manual React Application Creation

BlogPost_404

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Thomas Rutzer

Thomas Rutzer

hay I’m Thomas, specialized in crafting unique interfaces & interactions for the browser platform. Meet me on twitter or github: @thomasrutzer

More from Medium

Redux, What is Redux, Why we use Redux.

Re-assigning a value to UseParams hook using useState hook.

Setup a mono repo in javascript with lerna