3.0.1 • Published 5 months ago

mst-persistent-store v3.0.1

Weekly downloads
-
License
MIT
Repository
github
Last release
5 months ago

Mobx State Tree Persistent Store

A factory to easily create Persistent Mobx State Tree Store Provider and consumer hook.

Installation

yarn add mst-persistent-store

@react-native-async-storage/async-storage and localforage are optional peer dependencies. You can use any storage you want by passing the storage object to the factory. But if you want to use the default storage, you need to install one of them. See Usage and Custom Storage Backend for more info about how to use default or custom storage.

For React

yarn add mobx-state-tree localforage

For React Native

yarn add mobx-state-tree @react-native-async-storage/async-storage

Usage

Usage is very simple.

Create Provider and Hooks

Below is an example on how to create the provider and consumer hook.

// store-setup.ts
import { types } from 'mobx-state-tree';
import createPersistentStore from 'mst-persistent-store';
import defaultStorage from 'mst-persistent-store/dist/storage';

const PersistentStore = types
  .model('RootStore', {
    name: types.string,
    age: types.number,
    premium: types.boolean,
    hydrated: types.boolean,
  })
  .actions((self) => ({
    hydrate() {
      self.hydrated = true;
    },
  }))
  .views((self) => ({
    get isAdult() {
      return self.age >= 18;
    },
  }));

export const [PersistentStoreProvider, usePersistentStore] = createPersistentStore(
  PersistentStore,
  defaultStorage,
  {
    name: 'Test User',
    age: 19,
    premium: false,
    hydrated: false,
  },
  {
    hydrated: false,
  },
  {
    logging: false,
    devtool: false,
  }
);

Add Provider to The Root Component

Wrap your app with the created Provider component.

// app.tsx
import { PersistentStoreProvider } from './store-setup';
import Main from './main';

export default function App() {
  return (
    <PersistentStoreProvider>
      <Main />
    </PersistentStoreProvider>
  );
}

Use the Store from Child Components

Consume store values using the hook.

// main.tsx
import { observer } from 'mobx-react-lite';
import { useEffect } from 'react';
import { usePersistentStore } from './store-setup';

const Main = observer(() => {
  const { name, age, isAdult, hydrated, hydrate } = usePersistentStore();

  useEffect(() => {
    hydrate();
  }, []);

  if (!hydrated) {
    return <p>Loading...</p>;
  }

  return (
    <div>
      <p>
        {name} is {age} years old and {isAdult ? 'is' : 'is not'} an adult.
      </p>
    </div>
  );
});

export default Main;

Custom Storage Backend

The above example uses the default storage. You can use any storage you want by passing the storage object to the factory.

Here is an example using react-native-mmkv as the storage.

import { MMKV } from 'react-native-mmkv';

const mmkv = new MMKV();

const setItem = (key: string, value: any) => mmkv.set(key, JSON.stringify(value));

const getItem = (key: string) => {
  const value = mmkv.getString(key);
  if (value) {
    return JSON.parse(value);
  }
  return null;
};

const removeItem = (key: string) => mmkv.delete(key);

const storage = {
  setItem,
  getItem,
  removeItem,
};

export const [PersistentStoreProvider, usePersistentStore] = createPersistentStore(
  PersistentStore,
  storage,
  {
    name: 'Test User',
    age: 19,
    premium: false,
    hydrated: false,
  },
  {
    hydrated: false,
  },
  {
    hydrated: false,
  }
);

API

createPersistentStore

Type Definition

export interface StorageOptions {
  setItem: (key: string, value: any) => Promise<void> | void;
  getItem: (key: string) => Promise<any | null> | any | null;
  removeItem: (key: string) => Promise<void> | void;
}

interface PersistentStoreOptions {
  storageKey: string;
  writeDelay: number;
  logging: boolean;
  devtool: boolean;
}
const createPersistentStore: <T extends IAnyModelType>(
  store: T,
  storage: StorageOptions,
  init: SnapshotIn<T>,
  blacklist?: PartialDeep<SnapshotIn<T>>,
  options?: Partial<PersistentStoreOptions>
) => readonly [React.FC, () => Instance<T>];

Arguments

paramtyperequireddescription
storeT extends IAnyModelTypeyesthe mst model to instantiate
storageStorageOptionsyesthe storage to use. Use defaultStorage from mst-persistent-store/storage to use the @react-native-async-storage/async-storage (for React Native) or localforage (for Web) backed default storage.
initSnapshotIn<T>yesthe init data of the store
blacklistPartialDeep<SnapshotIn<T>>nothe part of the store that should not be persisted
optionsPartial<PersistentStoreOptions>noVarious options to change store behavior

PersistentStoreOptions

All Properties are optional.

propertytypedefaultdescription
storageKeystringpersistentStorethe key to use as the localforage key. Must be changed when using multiple stores in the sameapp to avoid overriding data.
writeDelaynumber1500On Repeated Store Update, it's advisable to waita certain time before updating the persistent storage with new snapshot. This value controls thedebounce delay.
loggingbooleantrue is devfalse in prodWhether to enable logging.
devtoolbooleantrue in devfalse in prodWhether to integrate with mobx-devtool

License

This package is licensed under the MIT License.

Contribution

Any kind of contribution is welcome. Thanks!

3.0.1

5 months ago

3.0.0

5 months ago

2.1.1

5 months ago

2.1.0

5 months ago

2.0.0

5 months ago

1.2.6

10 months ago

1.2.5

2 years ago

1.2.4

2 years ago

1.2.3

2 years ago

1.2.2

3 years ago

1.2.1

3 years ago

1.2.0

3 years ago

1.1.0

3 years ago

1.0.3

3 years ago

1.0.2

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago