ueno-llc / react-native-starter

Professional react-native starter kit with everything you'll ever need to deploy rock solid apps
https://ueno-llc.github.io/react-native-starter
MIT License
573 stars 89 forks source link

Combine models #205

Closed Amurmurmur closed 5 years ago

Amurmurmur commented 5 years ago

Describe the bug I'm not really clear, I think it is an issue of how I use mobx, but I just wanted to have your opinion on the models structure. I have a UI model from the boilerplate for all the ui updates. Can I combine it with other models that I want to implement like LOGIN, USER, etc. I get a weird behaviour when I do the following:

import { AsyncStorage } from "react-native";
import { types, flow, onSnapshot } from "mobx-state-tree";
import makeInspectable from "mobx-devtools-mst";

import { UI } from "./models/UI";
import { LOGIN } from "./models/LOGIN";
import debounce from "lodash/debounce";

export const Store = types
  .model("Store", {
    UI,
    LOGIN,
    isHydrated: false
  })
  .actions(self => ({
    hydrate: flow(function* hydrate() {
      yield self.UI.hydrate();
      yield self.LOGIN.hydrate();
      self.isHydrated = true;
    })
  }))
  .create({
    UI: {},
    LOGIN: {}
  });

// Persist snapshots
onSnapshot(
  Store.UI,
  debounce(
    snapshot => AsyncStorage.setItem("UI", JSON.stringify(snapshot)),
    1000
  )
);

onSnapshot(
  Store.LOGIN,
  debounce(
    snapshot => AsyncStorage.setItem("LOGIN", JSON.stringify(snapshot)),
    1000
  )
);

if (__DEV__) {
  makeInspectable(Store.UI);
  makeInspectable(Store.LOGIN);
}

My Login model:

import { AsyncStorage } from 'react-native';
import { types, flow, applySnapshot } from 'mobx-state-tree';

export const LOGIN = types.model('LOGIN', {
    token: types.optional(types.string, ''),
    fetching: types.optional(types.boolean, false),
    error: types.optional(types.boolean, false)
  })
  .actions(self => ({
    login(username?: string, password?: string) {
      if (username && password) {

      }
    },
    logout() {

    },
    hydrate: flow(function* () {
      const data = yield AsyncStorage.getItem('LOGIN');
      if (data) {
        applySnapshot(self, JSON.parse(data));
      }
    }),
  }))
  .views(self => ({
    get token() {
      return self.token
    },
    get isFetching() {
      return self.fetching
    },
    get error() {
      return self.error
    }
  }));

Expected behavior Should initialize models just fine.

Screenshots If applicable, add screenshots or a video to help explain your problem.

image

Environment

Additional context

Run react-native info in your terminal and paste its contents here. React Native Environment Info: System: OS: macOS 10.14.2 CPU: (4) x64 Intel(R) Core(TM) i7-7567U CPU @ 3.50GHz Memory: 65.14 MB / 16.00 GB Shell: 3.2.57 - /bin/bash Binaries: Node: 11.6.0 - /usr/local/bin/node Yarn: 1.13.0 - /usr/local/bin/yarn npm: 6.5.0 - /usr/local/bin/npm Watchman: 4.9.0 - /usr/local/bin/watchman SDKs: iOS SDK: Platforms: iOS 12.1, macOS 10.14, tvOS 12.1, watchOS 5.1 Android SDK: API Levels: 22, 23, 24, 25, 26, 27 Build Tools: 23.0.1, 23.0.2, 23.0.3, 25.0.0, 25.0.1, 25.0.2, 25.0.3, 26.0.1, 26.0.2, 27.0.0, 27.0.1, 27.0.2, 27.0.3 IDEs: Android Studio: 3.1 AI-173.4907809 Xcode: 10.1/10B61 - /usr/bin/xcodebuild npmPackages: react: 16.7.0 => 16.7.0 react-native: 0.57.8 => 0.57.8 npmGlobalPackages: react-native-cli: 2.0.1 react-native-git-upgrade: 0.2.7

birkir commented 5 years ago

Try comment out your hydration calls, you may have a malformed data in AsyncStorage. That's the only thing I can think of, as the code looks fine to me.

Do you have a repro available?

Amurmurmur commented 5 years ago

@birkir Literally nothing else was changed, it's just a boilerplate, if you copy paste my code above, it's exactly what I have.

UPDATE: Tried what you've mentioned same thing happens :/

So the following inside the store/index.tsx does not work as well, same error is thrown:

import { types, flow, onSnapshot } from "mobx-state-tree";
import makeInspectable from "mobx-devtools-mst";

import { UI } from "./models/UI";
import { LOGIN } from "./models/LOGIN";

export const Store = types
  .model("Store", {
    UI,
    LOGIN,
    isHydrated: false
  })
  .actions(self => ({
    hydrate: flow(function* hydrate() {
      yield self.UI.hydrate();
      yield self.LOGIN.hydrate();
      self.isHydrated = true;
    })
  }))
  .create({
    UI: {},
    LOGIN: {}
  });

if (__DEV__) {
  makeInspectable(Store.UI);
  makeInspectable(Store.LOGIN);
}
Amurmurmur commented 5 years ago

@birkir No? no takers ? Lol

jeremybarbet commented 5 years ago

This issue/question is more about mobx-state-tree than our starter kit.

You should take a look at the MBT's references, which sounds what you are looking for: https://github.com/mobxjs/mobx-state-tree#references-and-identifiers

Amurmurmur commented 5 years ago

@jeremybarbet Got it thank you very much for your help ! 👍