0

I'm trying to create a rootStore with two stores, currentUser, and AuthUser, I created a context, and tried to use it with useContext, but for some reason without success

RootStore and rootStore Context:

export class RootStore {
  @observable appName = 'Emasa';
  @observable appLoaded = false;
  userStore: UserStore;
  authStore: AuthStore;
  constructor() {
    this.userStore = new UserStore(this);
    this.authStore = new AuthStore(this);
  }
  @action setAppLoaded(): void {
    this.appLoaded = true;
  }
}
export const RootStoreContext = createContext(new RootStore())

CurrentUser Store:

export class UserStore extends BaseAPI {
  @observable currentUser: UserModel | null = null;
  @observable loadingUser = false;
  @observable updatingUser = false;
  @observable updatingUserErrors = false;
  constructor(rootStore: RootStore) {
    super(rootStore);
  }
  @action pullUser = async(): Promise<UserModel> => {
    this.loadingUser = true;
    try{
      const currentUser:UserModel = await this.get('/users/me', {
        Cookie: `Access-Token=${this.rootStore.authStore.token};`
      }).then(action(({ data }:any) => {
        this.currentUser = new UserModel(data)
        return data;
      }))
      this.loadingUser = false;
      return currentUser
    }catch(error){
      this.loadingUser = false;
      this.currentUser = null;
      this.rootStore.authStore.isAuth = false;
      throw error
    }
  }
}

and authStore:

const Cookie = new CookieUniversal()
export class AuthStore extends BaseAPI {
  @observable token = Cookie.get('Access-Token')
  @observable isAuth = false
  @observable inProgress = false
  @observable errors = undefined
  constructor(rootStore: RootStore) {
    super(rootStore)
    reaction(
      () => this.isAuth,
      (value) => {
        if (!value) return this.remove()
        if (value && !verify(this.token, apiSecret)) return this.remove()
      }
    )
  }
  @action async login(login: string, password: string): Promise<UserModel> {
    this.inProgress = true
    this.errors = undefined
    try {
      const response: UserModel = await this.post('/login', {
        login,
        password,
      }).then(() => this.rootStore.userStore.pullUser())
      if(response instanceof UserModel) this.isAuth = true;
      return response
    } catch (error) {
      this.errors = error.response && error.response.body && error.response.body.errors
      throw error
    }
  }
  @action logout(): Promise<void> {
    this.remove()
    return Promise.resolve()
  }
  @action remove(): void {
    Cookie.remove('Access-Token')
    this.rootStore.userStore.currentUser = null
  }
}

jsx:

const App: React.FunctionComponent = () => {
  const { theme } = useAppTheme();
  const { authStore, userStore } = useContext(RootStoreContext);
  useEffect(() => {
    async function start() {
      await userStore.pullUser();
    }
    start();
  }, []);
  console.log(userStore.currentUser, "user");
  console.log(authStore.isAuth, "isAuth");
  return (
    <ThemeProvider theme={theme}>
      <a>{authStore.isAuth}</a>
    </ThemeProvider>
  );
};

enter image description here

I'm not able to solve this, for some reason when opening the page, I make my request valid the token all correctly, but it seems that my store doesn't work I always take the current user as udnefined and my isAuth as false, I can't find where I am wrong with MOBX or react

if anyone can help I am grateful

Ming
  • 1,349
  • 4
  • 13
  • 36

1 Answers1

0

You have to wrap your app with <RootStoreContext.Provider /> and provide RootStore instance as initial value.

Check useContext doc for examples of using Context with hooks

0xLLLLH
  • 34
  • 5