mobxjs / mobx-react

React bindings for MobX

Home Page:https://mobx.js.org/react-integration.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

The problem of `useRef` to keep the store instance

Chr15t0pher opened this issue · comments

When I migrate to mobx v6 and mobx-react v7, using useRef to keep store instance doesn't work any more, check the code below.

import React, { useRef } from "react";
import { observable, action, reaction } from "mobx";
import { observer } from "mobx-react";
class AppStore {
  @observable
  num = 1;

  constructor() {
    reaction(
      () => this.num,
      (data) => console.info(data)
    );
  }

  @action
  change = () => {
    this.num = this.num + 1;
  };
}

export default observer(() => {
  const { change, num } = useRef(new AppStore()).current;
  return <button onClick={change}>{num}</button>;
});

And I also try it in class component, it didn't work either.

@observer
export default class App extends React.Component {
  store = new AppStore()

  render() {
    return (
      <button onClick={ this.store.change }>{ this.store.num }</button>
    )
  }
}

But all these work below mobx-react v7, I have no idea how to solve this problem.

Intended outcome

Click the button, the num increase and view re-render, reaction callback is invoked.

Actual outcome

the num increase but view doesn't re-render, reaction callback isn't invoked.

How to reproduce the issue

https://codesandbox.io/s/adoring-shirley-dr23s?file=/src/App.tsx

Versions

mobx 6.0.1
mobx-react 7.0.0

Since mobx6 you have to call makeObservable(this) in the store's constructor:
https://mobx.js.org/migrating-from-4-or-5.html#upgrading-classes-to-use-makeobservable

Since mobx6 you have to call makeObservable(this) in the store's constructor:
https://mobx.js.org/migrating-from-4-or-5.html#upgrading-classes-to-use-makeobservable

I see, thanks a lot.