Cross-component, persistable useState() effect, without context
Why?
Even with the advent of React hooks, cross-component shared state
is still being solved with either context/provider hooks (messy), or traditional
stores like redux/mobx (messier). This store more or less mirrors the signature of
the incredibly elegant useState()
hook, with optional local persistence built-in.
API
useStore(namespace, [initialValue=undefined], [options={}])
returns [ value, setValue ]
pair, identical to useState()
in React
// note: import { useStore } from 'use-store' will continue to work // must be called inside a React componentlet value setValue = // value = undefined// value = 3
Arguments
namespace
(string) required - this is the reference you'll share throughout the app for a specific value. E.g.useStore('myValue')
initialValue
(anything) optional - optional default value which will be set by the first component that encounters this hook on a given namespace. This will be ignored if persist is enabled and value found locally.options
(object) optional - options for the hook (see below):persist
(boolean, default=false)
useStore()
above
globalStore.set(namespace, initialValue, options) // params identical to For manually setting initial values and persist options so individual components don't have to (also to solve race conditions)
globalStore
Example (Elaborate)
// ComponentA.js { let value setValue = return <div> ComponentA:value = value <button onClick= > Increment </button> </div> }
// ComponentB.js { let value setValue = return <div> ComponentB:value = value // this will increment as ComponentA clicks are registered <ComponentA /> </div> }
Example (Event Handlers)
{ let value setValue = // traditional event handler no longer needed for inputs const changeHandler = return <div> <!-- this still works --> <input value=value onChange=changeHandler /> <!-- but so does this no need to wrap the setter in an event handler --> <input value=value onChange=setValue /> </div> }