1

I am using MobX-state-tree for state management and mst-persist to persist my data. The problem is when I reload the app the initial data of the store renders first and then the persist data gets loaded. So whenever I want to check a persisted data in my store the initial data renders first, My function runs based on that and when everything stopped rendering my persisted data renders. This code is a simplified version of my problem. When app renders first I get "false" in my console then I get "True". Even after I comment out the setTemp(). Is there any way to fix this or is there another package that I can use for persisting MST?

Rootstore.ts

import {
  types,
  Instance,
  applySnapshot,
  getSnapshot,
} from 'mobx-state-tree';
import {createContext, useContext} from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {persist} from 'mst-persist';


const RootStore = types
  .model('RootStore', {
    temp: false,
  })
  .actions(store => ({
    setTemp() {
      applySnapshot(store, {...getSnapshot(store), temp: true});
    },
  }));
  
  let _store: any = null;

export function initializeStore() {
  _store = RootStore.create({});
  persist('@initstore', _store, {
    storage: AsyncStorage,
    jsonify: true,
    whitelist: ['temp'], 
  });

  return _store;
}
export type RootInstance = Instance<typeof RootStore>;
const RootStoreContext = createContext<null | RootInstance>(null);
export const Provider = RootStoreContext.Provider;

export function useStore(): Instance<typeof RootStore> {
  const store = useContext(RootStoreContext);
  if (store === null) {
    throw new Error('Store cannot be null, please add a context provider');
  }
  return store;
}

App.ts

import {initializeStore,Provider} from './src/store/RootStore';

const store = initializeStore();

<Provider value={store}>
  <RootStack /> //the App
</Provider>

InitializeScreen.ts

import {observer} from 'mobx-react-lite';
import {useStore} from '../../store/RootStore';

const InitializeScreen = observer((): JSX.Element => {
  const {setTemp,temp} = useStore();
  useEffect(() => {
    setTemp()
  }, []);

  console.log('init page',temp); // <-- Every time app reloads reneders false then true
  
  
  return (
    <Text>InitializeScreen</Text>
  );
});

export default InitializeScreen;
fatima
  • 11
  • 1
  • Maybe you could take some inspiration from the Ignite React Native template? [They don't render anything until the root store has been initialised](https://github.com/infinitered/ignite/blob/7b8779931c3d43c45f9e0c44ed64cf1b3767b7f6/boilerplate/app/app.tsx#L32-L71) and [they set up the `RootStoreModel` instance asynchronously](https://github.com/infinitered/ignite/blob/7b8779931c3d43c45f9e0c44ed64cf1b3767b7f6/boilerplate/app/models/root-store/setup-root-store.ts#L27-L55). – Tholle Jun 27 '22 at 09:25

0 Answers0