Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persist changed value from true to false #26

Open
ghost opened this issue Feb 26, 2020 · 3 comments
Open

Persist changed value from true to false #26

ghost opened this issue Feb 26, 2020 · 3 comments
Labels
kind: support Asking for support with something or a specific use case solution: duplicate This issue or pull request already exists solution: intended behavior This is not a bug and is expected behavior solution: needs test This issue requires creating a test to assuredly close out

Comments

@ghost
Copy link

ghost commented Feb 26, 2020

Hi.

Environment info

React native info output:

 System:
    OS: Linux 5.3 Ubuntu 18.04.4 LTS (Bionic Beaver)
    CPU: (8) x64 Intel(R) Core(TM) i7-9700 CPU @ 3.00GHz
    Memory: 12.78 GB / 31.23 GB
    Shell: 4.4.20 - /bin/bash
  Binaries:
    Node: 12.16.1 - /usr/bin/node
    Yarn: 1.21.1 - /usr/bin/yarn
    npm: 6.13.4 - /usr/bin/npm
  npmPackages:
    react: 16.9.0 => 16.9.0 
    react-native: 0.61.5 => 0.61.5

The problem is, when i persist RootStore with nested AuthStore, all my boolean value form AuthStore become from true to false.

When i just console.log its value, i have this behaviour

const { isLoading } = authStore;

console.log('isLoading => ', isLoading);

image

It is RootStore with nested AuthStore

import { types } from 'mobx-state-tree';
import { connectReduxDevtools } from 'mst-middlewares';
import AuthStore from './auth.store';
import { persist } from 'mst-persist';
import AsyncStorage from '@react-native-community/async-storage';

let store: any = null;

export default () => {
  if (store) return store;

  const RootStore = types
    .model('RootStore', {
      identifier: types.optional(types.identifier, 'RootStore'),
      auth: AuthStore,
    });

  store = RootStore.create({
    auth: {
      isLoading: true,
    },
  });

  /**
   * Not working in debug mode
   */
  persist('rootStore', store, {
    storage: AsyncStorage,
  }).then(() => {});

  // @ts-ignore
  if (__DEV__ && Boolean(window.navigator.userAgent)) {
    connectReduxDevtools(require('remotedev'), store);
  }

  return store;
};

There is AuthStore

import { types } from 'mobx-state-tree';
const AuthStore = types
  .model({
    isLoading: types.optional(types.boolean, true),
  });

export default AuthStore;
@ghost
Copy link
Author

ghost commented Feb 26, 2020

Can i persist only nested store?
How can i add isLoading to whiteList if it is nested store?

@agilgur5
Copy link
Owner

agilgur5 commented Feb 27, 2020

Thanks for narrowing this down to a more minimal example @YanisKondakov , was hard to read through before.

You still didn't quite provide an example of where this code is run:

const { isLoading } = authStore;

console.log('isLoading => ', isLoading);

For it to log twice, it must've been run twice, and that's not in the code you've listed. authStore also isn't defined anywhere.

Since you have isLoading defaulted to true, this shouldn't be affected by #5 , it should initialize an empty storage to true as well.
It sounds like your problem is that isLoading is changed to false in your app somewhere, and then false gets persisted. So when your app hydrates data from storage, it will hydrate to false.

Can i persist only nested store?

Any persisted store will persist all its nested stores as well. But I'm struggling to fully understand what you meant here as there's some grammatical errors.

How can i add isLoading to whiteList if it is nested store?

Did you mean to blacklist? In either case, you've hit the mark here, there's no way to specifically whitelist or blacklist a nested property right now. You can blacklist auth, but not auth.isLoading.

This is a problem I'm looking to fix soon once I've got Transforms #16 merged in, likely using a similar dotted syntax as above. Deep blacklists are relatively easy to implement, but deep whitelists are more complex (especially if any conflict handling is added).
This has popped up in my own usage as well, such as agilgur5/react-native-manga-reader-app#27, so it's a known issue, but I never filed a formal issue for it. Will do that now. EDIT: see #27

There are some workarounds for this, but they're all a bit hacky without Transforms 😕 Like one is to manually set your storage to the default of true. Sorry about that.


Side note:

isLoading: types.optional(types.boolean, true)

can just be simplified to:

isLoading: true

Per https://mobx-state-tree.js.org/concepts/trees#creating-models , they're equivalent.

@agilgur5 agilgur5 added solution: duplicate This issue or pull request already exists solution: intended behavior This is not a bug and is expected behavior labels Feb 27, 2020
@ghost
Copy link
Author

ghost commented Feb 27, 2020

Thank you @agilgur5 for the detailed answer. And sorry for my english.

The example of where this code is run

const { isLoading } = authStore;

console.log('isLoading => ', isLoading);

is

import React from 'react';
import createStore from './stores';
import { inject, observer, Provider } from 'mobx-react';

//This is a RootStore
const store = createStore();

const App = inject(({ authStore }) => ({ authStore }))(
  observer(({ authStore }: any) => {
   const { isLoading } = authStore;
  
   console.log('isLoading => ', isLoading);

    if (isLoading) {
       return <SplashScreen />;
    }

    return (...);
  }),
);

const AppProvider = () => (
  <Provider rootStore={store} authStore={store.auth} profileStore={store.profile}>
    <App />
  </Provider>
);

export default AppProvider;

It sounds like your problem is that isLoading is changed to false in your app somewhere, and then false gets persisted. So when your app hydrates data from storage, it will hydrate to false.

As you can see, isLoading is not changed to false anywhere. And if i remove data hydrating, isLoading log only once and it's value is true.

@agilgur5 agilgur5 changed the title Persist change store value from 'true' to 'false'. Persist change store value from true to false. Jul 19, 2023
@agilgur5 agilgur5 changed the title Persist change store value from true to false. Persist change store value from true to false Jul 19, 2023
@agilgur5 agilgur5 changed the title Persist change store value from true to false Persist changed value from true to false Jul 19, 2023
@agilgur5 agilgur5 added kind: support Asking for support with something or a specific use case solution: needs test This issue requires creating a test to assuredly close out labels Jul 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: support Asking for support with something or a specific use case solution: duplicate This issue or pull request already exists solution: intended behavior This is not a bug and is expected behavior solution: needs test This issue requires creating a test to assuredly close out
Projects
None yet
Development

No branches or pull requests

1 participant