If you don’t know what MOBx is please read this article

In this article, we will show some best practices for mobx React and follow the step-by-step rules. When you have a problem, follow these rules.

This article requires you to have a basic understanding of Mobx stores, if not read the official documentation.

Stores represent UI state

Always remember that your stores represent your UI state, which means that when you store your stores, even if you close the page, open it again, and load the stores, you should get the same page. Although stores are not a local database role, they still store UI state such as whether buttons are visible or what is in the input.

class SearchStore {
  @observable searchText;

  @action
  setSearchText = (searchText) = > {
    this.searchText = searchText
  }
}

@observer
class SearchInput extends React.Component {

  handleInputChanged = (event) = > {
    const { searchStore } = this.props;
    searchStore.setSearchText(event.target.value);
  }

  render() {
    const { searchStore } = this.props;
    return (
      <input
        value={searchStore.searchText}
        onChange={this.handleInputChanged}
      />); }}Copy the code

Separate your REST API requests from store actions

It is not recommended to put REST API request functions in stores, as this makes the request code difficult to test. You can try to put these request functions in a class, put the code of the class next to the store, and create the class when the Store is created. Then when you test, you can also gracefully mock out data from these classes.

class TodoApi {

  fetchTodos = (a)= > request.get('/todos')}class TodoStore {

  @observable todos = [];

  constructor(todoApi) {
    this.todoApi = todoApi;
  }

  fetchTodos = async() = > {const todos = await this.todoApi.fetchTodos();

    runInAction((a)= > {
      this.todos = todos; }); }}// In your main function
const todoApi = new TodoApi();
const todoStore = new TodoStore(todoApi);
Copy the code

Put your business logic in stores

Try not to write business logic into your components. When you write business logic in components, there is no way to locate errors in time, because your business logic is scattered among different components, making it difficult to define the behavior of which code is involved in the error. It is better to put the business logic in the stores method and call it from the component.

Avoid using global Store instances

Try to avoid using global Store instances because it is difficult to write coherent and reliable component tests. Instead, you can use providers to inject your store into the props of your Component instance. This way you can easily mock these stores to test.

const searchStore = new SearchStore();

const app = (
  <Provider searchStore={searchStore}>
    <SearchInput />
  </Provider>
);

ReactDom.render(app, container);
Copy the code

mobxjs/mobx-react

Changing properties is only allowed in stores

Do not directly manipulate store property values in components. Because only store can modify its own properties. When you want to change properties, use the corresponding store method. Otherwise your property changes will be scattered all over the place and out of control, which is hard to debug.

Always remember the component declaration@observer

Use @Observer to update the state of each component declaration. Otherwise, in nested components, each state update involves a re-rendering of the parent component level if the child component is not declared. When you use @Observer, the number of re-rendered components is significantly reduced.

use@computed

As in the example below, use the @computed attribute to handle some logic involving multiple attributes. Using @computed reduces the frequency of such judgment-class business logic in components.

class ApplicationStore {

  @observable loggedInUser;

  @observable isInAdminMode;

  @computed isAdminButtonEnabled = () => {
    return this.loggedInUser.role === 'admin'&& this.isInAdminMode; }}Copy the code

You don’t need the React Router to manage state

You don’t need the React Router to manage state. As I said earlier, your Store represents the state of your app. When you ask the Router to manage the state of an application, that state is stripped from the Store. So try to use store to store all the UI state, so that the store properties are what your interface gets.

Prefer to write controllable components

Writing controllable components will greatly reduce the complexity of your tests and make your components easier to manage.

Forms – the React

By Daniel Bischoff

Mobx React — Best Practices

Translation: Dominic Ming