How to use Mobx with create-react-app

Như tiêu đề bài viết sử dụng Mobx trong create-react-app như thế nào. Các bạn thực hiện theo các bước sau:

Tạo ứng dụng react với create-react-app

Để tạo ứng dụng React với create-react-app, bạn sử dụng command sau để tạo React App với phiên bản create-react-app mới nhất

yarn create react-app [App Name] hoặc npx create-react-app [App Name]

Mình dùng yarn nên câu lệnh của mình: yarn create react-app create-app-with-mobx

Sau khi chạy xong lệnh, mình có được kiến trúc thư mục, chạy lệnh: yarn start để chạy ứng dụng lên

Ứng dụng chạy thành công

Tích hợp thư viện mobx vào ứng dụng

Bạn cần cài đặt thêm thư viện mobx, mobx-react để chạy được mobx, chạy lệnh: yarn add mobx mobx-react

Thực thi mã với mobx và mobx-react nào

Tạo kiến trúc thư mục như bên dưới

Với AppStore.js

import { observable, action } from 'mobx';

class AppStore {
  @observable counter = 0;

  @action
  incr() {
    this.counter++;
  }

  @action
  decr() {
    this.counter--;
  }
}

export const store = new AppStore;

Với:

  • @observable counter: khai báo biến counter được quan sát, khi biến counter thay đổi giá trị thì AppStore có thay đổi và kéo theo những component liên quan đang là người theo dõi (observer) sẽ phản ứng theo.
  • action: khai báo một hành động của AppStore.

Khi bạn tạo mã code như vậy vscode sẽ hiện thông báo đỏ

Cách khắc phục, bạn tạo file jsconfig.json ở ngoài thư mục gốc với nội dung sau

{  "compilerOptions": {    "experimentalDecorators": true  }}

Tích hợp mobx vào React app hiện tại

Tạo store và inject store vào trong App

Chúng ta xử dụng thư viện mobx-react và viết lại file index.js như sau

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'mobx-react';
import { store } from './store/AppStore';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(
  <React.StrictMode>
    <Provider AppStore={store}>
      <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

Sau đó chạy lại ứng dụng: yarn start

Ở bước này App sẽ bị lỗi nha các bạn, có thông báo lỗi ở console

Support for the experimental syntax ‘decorators-legacy’ isn’t currently enabled

Để fix lỗi này, chúng ta bật decorators-legacy lên. Cách đơn giản nhất là eject ứng dụng ra và chỉnh lại cấu hình của babel, gồm 2 thao tác sau:

  • Cài đặt thêm 2 thư viện với lệnh: yarn add -D @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties
  • Chạy lệnh: yarn eject để đẩy cấu hình react-app đã đóng gói và tùy chỉnh lại. Sau khi chạy xong lệnh chúng ta vào file package.json và chỉnh lại thuộc tính babel như sau
"babel": {
    "presets": [
      "react-app"
    ],
    "plugins": [
      ["@babel/plugin-proposal-decorators", { "legacy": true }],
      ["@babel/plugin-proposal-class-properties", { "loose": true }]
    ]
  }

Thao tác store bên trong component

Viết lại file App.js

import React, { PureComponent } from 'react';
import { inject, observer } from 'mobx-react';
import logo from './logo.svg';
import './App.css';

@inject('AppStore')
@observer
class App extends PureComponent {
  incr = () => {
    const { AppStore } = this.props;
    AppStore.incr();
  }

  render() {
    const { AppStore } = this.props;
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.js</code> and save to reload.
          </p>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
          </a>
          <p>{AppStore.counter}</p>
          <button onClick={this.incr}>Incr</button>
        </header>
      </div>
    );
  }


}

export default App;

Với:

  • @inject(‘AppStore’): inject decorator nhận đầu vào là 1 hoặc 1 mảng store cần đưa vào xử dụng trong component, nó sẽ được inject vào props của compent
  • @observer: khai báo component sẽ là một observer và phản ứng khi store (các thuộc tính được theo dõi trong store thay đổi) thay đổi

Như vậy là chúng ta đã chạy tích hợp thành công mobx với ứng dụng React

Rate this post

You May Also Like

About the Author: truongluu

Leave a Reply

Your email address will not be published. Required fields are marked *