A persistent state management library for React
MIT License
Create your own hooks that share state. Initialise your store with default values and use an API that infers type information for you.
Features
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 your hook
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 application
import { 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:
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.