Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Persist Mobx State Tree in React Native?

I need to persist a MST Store in React Native. The data is changed seldomly.

I'm confused between using AsyncStorage and AutoRun.

like image 216
Aswin Mohan Avatar asked Jun 16 '18 12:06

Aswin Mohan


People also ask

How do you persist MobX state?

To persist this observable we simply add a persist to it: When you update the observable variable, which is marked with persist , mobx-persist will automatically save the change using AsyncStorage.

Does MobX need state tree?

Ten reasons you should use MobX-State-Tree: Your data is mutable, but can only be mutated in "actions", so it's easy to use but also protected. Via runtime type checking, you can't accidentally assign the wrong data type to a property. TypeScript can infer static types from your runtime types automatically.

How does MobX-state-tree work?

The tree consists of mutable, but strictly protected objects enriched with run-time type information. In other words; each tree has a shape (type information) and state (data). From this living tree, immutable and structurally shared snapshots are generated automatically.


1 Answers

For persisting MST stores, you might be interested in using mst-persist, which, per the README, is currently a small wrapper around MST's onSnapshot and applySnapshot (disclaimer: I'm the creator).

To persist data in React Native with mst-persist backed by AsyncStorage, one would do:

import { types } from 'mobx-state-tree'
import { AsyncStorage } from 'react-native'
import { persist } from 'mst-persist'

const SomeStore = types.model('Store', {
  name: 'John Doe',
  age: 32
})

const someStore = SomeStore.create()

persist('some', someStore, {
  storage: AsyncStorage,  // default: localStorage
  jsonify: true  // if you use AsyncStorage, this should be true
                  // default: true
  whitelist: ['name']  // only these keys will be persisted
}).then(() => console.log('someStore has been hydrated'))

My original use case for mst-persist was for React Native and the current README will actually point you to a commit in an OSS RN manga reader app I made as an example.

If you're interested in how to do it with MST without another library like mst-persist, the persistence source code is actually < 50 LoC currently. And minus some features, it's a brisk < 20 LoC:

import { onSnapshot, applySnapshot } from 'mobx-state-tree'

export const persist = (name, store, options = {}) => {
  let {storage, jsonify} = options

  onSnapshot(store, (_snapshot) => {
    const snapshot = { ..._snapshot }
    const data = !jsonify ? snapshot : JSON.stringify(snapshot)
    storage.setItem(name, data)
  })

  return storage.getItem(name)
    .then((data) => {
      const snapshot = !jsonify ? data : JSON.parse(data)
      applySnapshot(store, snapshot)
    })
}

There are a handful of other examples out in the wild that show similar functionality as well, such as this gist that mst-persist is partly inspired by, this repo that uses HoCs and PersistGates similar to redux-persist, and this gist that takes multiple stores as an argument.

like image 80
agilgur5 Avatar answered Oct 07 '22 21:10

agilgur5