⚡ A persistent state management library for React. Create your own hooks that share data across components
View Demo
·
Report Bug
·
View on npm
Create your own hooks that share state. Initialise your store with default values and use an API that infers type information for you.
Features
- Persistence: data is serialised and persisted to local storage by default, and hydrated automatically
- Type safety: full TypeScript integration with type inference from default values
- Reactive design: state updates are shared across components
- Simplicity: does not require any component wrapping, or use of other abstractions such as the Context API
At a high level, it is generally suggested to create a store.ts
file in which you set up your exported hook functions. Then these can be imported and used in components.
-
Install NPM package
npm install react-persist-store
-
Set up your
Store
and create yourhook
import createStore, { Store } from "react-persist-store"; const defaultValues: Store = { user: { firstName: "", lastName: "", badges: [], // In TypeScript this is never[], you can change this behaviour with createStore<YourStoreType>(...) }, posts: [ /** ... */ ], }; // You can pass options to customise the type of storage, "local", "session", or false to disable persistence // const store = createStore(defaultValues, { storage: 'session', namespace: 'custom' }); const createHook = createStore(defaultValues); export const useUser = createHook("user")
-
Use the
hook
anywhere in your applicationimport { useUser } from "./store" const Component = () => { // Hooks do not take arguments, and return only: // data - your data with types inferred from your store, or the generic you passed in // update - a function what takes a partial copy of data to update // clearAll - clear all state, including browser storage for this hook const { data, update, clearAll } = useUser() const { firstName, lastName } = data const fullName = `${firstName}${lastName ? ' ' + lastName : ''}` return ( <p> {fullName} </p> ) } export default Component
The library exports a default function which takes a type of Store
. This is just an object where keys are a namespace to a Document
.
A Document
is any object that can be serialised into JSON. That is, any data type that is one of null
, number
, string
, boolean
, or an array
or object
containing any combination of these.
This limitation is enforced, and this library is not suitable for storing data that is not serialisable.
When you call createStore
you get back a function that can create hooks.
import createStore, { Store, Document } from 'react-persist-store'
const document: Document = { example: '' }
const defaultValues: Store = {
namespaceName: document
}
const createHook = createStore(defaultValues);
You can create as many namespace names as you wish. Each refers to a Document
type.
The next step is to create hooks themselves. When you call createHook
above, a closure is created that contains an event emitter
. This event emitter is shared under the hood to users of the hook, and permits them to share updates to state.
The name that you pass to createHook
is restricted to keyof typeof defaultValues
. In other words, it has to be a key (a namespace name) in the top level of the default values passed to createStore
.
export useStore = createHook("namespaceName")
Each created hook is called without arguments. Once called, no further action is required on the part of the hook.
Unless disabled, the hook first attempt to hydrate state from browser storage, based on its namespace name. This gets it up to date with the current state as updates to state are synchronised with browser storage. If this does not exist, then state is initialised from the default values.
It then returns an object with three properties:
- data: is your (typed) data
- update: takes a partial or full copy of your data and updates component state and local storage
- clearAll: clears browser state associated with the hook and resets data to the default value
import { useUser } from "./<file_exporting_hook>"
const Component = () => {
const { data, update, clearAll } = useUser()
return <p>{data.example}</p>
}
Distributed under the MIT License. See LICENSE
for more information.