Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't MobX v6.x work as expected in React with Typescript?

I am currently writing a React App, that should be able to rerender components when the value of any observable changes. The problem is, that I can't get email to rerender if it changes.

store.ts

export class ExampleStore {
  @observable email = 'hello';

  @action setEmail(email: string) {
    this.email = email;
  }
}

index.tsx

const stores = {
  exampleStore
};

ReactDOM.render(
  <Provider {...stores}>
    <App />
  </Provider>,
  document.querySelector('#root')
);

App.tsx

interface Props {
  exampleStore?: ExampleStore;
}

@inject('exampleStore')
@observer
export class App extends React.Component<Props, {}> {
  componentDidMount() {
    setInterval(() => {
      this.props.exampleStore!.setEmail(Math.random() * 10 + '');
    }, 2500);
  }

  render() {
    const { email } = this.props.exampleStore!;
    return <div>{email}</div>;
  }
}

I have seen many examples use the useContext hook, but I have to use class components. I am not sure why this isn't calling the render function again. I have mobx and mobx-react installed.

like image 903
Keimeno Avatar asked Dec 18 '22 12:12

Keimeno


1 Answers

Are you using MobX 6?

Decorator API changed a little bit, now you need to use makeObservable method inside constructor to achieve same functionality as before:

class ExampleStore {
  @observable email = "hello";

  constructor() {
    makeObservable(this);
  }

  @action setEmail(email) {
    this.email = email;
  }
}

Althought there is new thing that will probably allow you to drop decorators altogether, makeAutoObservable:

class ExampleStore {
  email = "hello2";

  constructor() {
    // Don't need decorators now, just this call
    makeAutoObservable(this);
  }

  setEmail(email) {
    this.email = email;
  }
}

More info here: https://mobx.js.org/react-integration.html

Codesandbox: https://codesandbox.io/s/httpsstackoverflowcomquestions64268663-9fz6b?file=/src/App.js

like image 177
Danila Avatar answered Mar 05 '23 00:03

Danila