Created
February 23, 2024 21:43
-
-
Save dantldev/32ce425c8f4062eb6e84af38f878bc73 to your computer and use it in GitHub Desktop.
zustand quick docs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* live demo https://codesandbox.io/p/devbox/confident-bessie-ldx396?file=%2Fsrc%2FApp.tsx%3A1%2C34&layout=%257B%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522rootPanelGroup%2522%253A%257B%2522direction%2522%253A%2522horizontal%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522id%2522%253A%2522ROOT_LAYOUT%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522clsz5b2c400073j6j1kpfsrwy%2522%252C%2522sizes%2522%253A%255B100%252C0%255D%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522EDITOR%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522id%2522%253A%2522clsz5b2c300023j6jdruu5tjb%2522%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522SHELLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522id%2522%253A%2522clsz5b2c300043j6jyrkssxg1%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522DEVTOOLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522id%2522%253A%2522clsz5b2c400063j6j2ehb6ut9%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%252C%2522sizes%2522%253A%255B69.75503441746712%252C30.244965582532885%255D%257D%252C%2522tabbedPanels%2522%253A%257B%2522clsz5b2c300023j6jdruu5tjb%2522%253A%257B%2522id%2522%253A%2522clsz5b2c300023j6jdruu5tjb%2522%252C%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522clsz5f5j700023j6j4pq4ijc8%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522FILE%2522%252C%2522initialSelections%2522%253A%255B%257B%2522startLineNumber%2522%253A1%252C%2522startColumn%2522%253A34%252C%2522endLineNumber%2522%253A1%252C%2522endColumn%2522%253A34%257D%255D%252C%2522filepath%2522%253A%2522%252Fsrc%252FApp.tsx%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%255D%252C%2522activeTabId%2522%253A%2522clsz5f5j700023j6j4pq4ijc8%2522%257D%252C%2522clsz5b2c400063j6j2ehb6ut9%2522%253A%257B%2522id%2522%253A%2522clsz5b2c400063j6j2ehb6ut9%2522%252C%2522tabs%2522%253A%255B%257B%2522type%2522%253A%2522UNASSIGNED_PORT%2522%252C%2522port%2522%253A5173%252C%2522id%2522%253A%2522clsz5foqi007b3j6j0wjer37l%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522path%2522%253A%2522%252F%2522%257D%255D%252C%2522activeTabId%2522%253A%2522clsz5foqi007b3j6j0wjer37l%2522%257D%252C%2522clsz5b2c300043j6jyrkssxg1%2522%253A%257B%2522id%2522%253A%2522clsz5b2c300043j6jyrkssxg1%2522%252C%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522clsz5bmy8008t3j6jrbhvqcl8%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522TERMINAL%2522%252C%2522shellId%2522%253A%2522clsz5bn7h020rdcip7k97asgz%2522%257D%255D%252C%2522activeTabId%2522%253A%2522clsz5bmy8008t3j6jrbhvqcl8%2522%257D%257D%252C%2522showDevtools%2522%253Atrue%252C%2522showShells%2522%253Afalse%252C%2522showSidebar%2522%253Atrue%252C%2522sidebarPanelSize%2522%253A15%257D | |
**/ | |
import { createStore, useStore } from "zustand"; | |
import { immer } from "zustand/middleware/immer"; | |
/** | |
* Note: its a good idea to define the type of the store | |
* so on another file you can import it and use it | |
*/ | |
export interface MainStore { | |
user: { | |
id: number; | |
name: string; | |
} | null; | |
} | |
/** | |
* same with the actions | |
*/ | |
export interface MainStoreActions { | |
setUser: (args: MainStore["user"]) => void; | |
} | |
const initialState: MainStore = { | |
user: null, | |
}; | |
export const MainStore = createStore( | |
// immer is very cool to not have to spread the state all the time | |
immer<MainStore & MainStoreActions>( | |
(set, get /** you dont use much get here */) => ({ | |
...initialState, | |
// here you can define whatever you want async or not. It doesnt matter. | |
setUser: (newValues) => { | |
set((state) => { | |
state.user = newValues; | |
}); | |
}, | |
/* | |
// define functions outside this scope is a little weird, maybe you can came up with something else | |
foo: (newValues) => { | |
functionOnAnotherFile(newValues, set, get); | |
} | |
// you can be tempted to set this in another file. But remember. You can have any number of stores so, | |
// it doesnt matter that much. You can do it here. | |
// you can make computed values | |
getNameInUppercase: () => { | |
const user = get().user; | |
return user ? user.name.toUpperCase() : ""; | |
} | |
*/ | |
}), | |
), | |
); | |
// export the store as a custom hook | |
export const useMainStore = () => { | |
return useStore(MainStore); | |
}; | |
// using the store outside a component to set state | |
export const setUser = () => { | |
MainStore.setState((state) => { | |
state.user = { id: 1, name: "test" }; | |
}); | |
}; | |
export const removeUser = () => { | |
MainStore.setState((state) => { | |
state.user = null; | |
}); | |
}; | |
// using the store outside a component to get state | |
export const getUser = MainStore.getState().user; | |
// making function and stuffs (if needed, but is better to stay inside the MainStore definition (above) so you dont | |
// mess up with disconnected proxies from immer and that kind of stuff) | |
export const getUserOrRedirect = () => { | |
const user = MainStore.getState().user; | |
if (!user) { | |
// do your redirect thing | |
return null; | |
} | |
return user; | |
}; | |
// usage on a react component | |
import { removeUser, setUser, useMainStore } from "./store/main.store"; | |
import "./App.css"; | |
function App() { | |
const { user } = useMainStore(); | |
if (!user) { | |
return ( | |
<> | |
<p>no user no party</p> | |
<button onClick={setUser}>set a user</button> | |
</> | |
); | |
} | |
return ( | |
<> | |
<p>hello {user.name}</p> | |
<button onClick={removeUser}>remove the user (logout)</button> | |
</> | |
); | |
} | |
export default App; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment