Skip to content

Latest commit

 

History

History
190 lines (138 loc) · 7.38 KB

README.md

File metadata and controls

190 lines (138 loc) · 7.38 KB

MIT License MIT License

npm npm


Logo

react-persist-store

⚡ 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

(back to top)

Getting Started

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.

Installation

  1. Install NPM package

    npm install react-persist-store
  2. 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")
  3. 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

(back to top)

Usage and How It Works

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>
}

(back to top)

License

Distributed under the MIT License. See LICENSE for more information.

(back to top)