1. 程式人生 > >React專案中使用Mobx狀態管理(二)

React專案中使用Mobx狀態管理(二)

並上一節使用的是普通的資料狀態管理,不過官方推薦使用裝飾器模式,而在預設的react專案中是不支援裝飾器的,需要手動啟用。

官方參考

 

一、新增配置

官方提供了四種方法, 

方法一、使用TypeScript,顧名思義該方法是專案使用typescript時的配置

方法二、使用babel-preset-mobx, 安裝並新增到.babelrc配置中,該方法需要升級一些依賴, 

  babel-core -> @/babel-core 7.x

  babel-loader -> @/babel-loader 8.x

  babel-preset-env -> @/babel-preset-env

  babel-preset-react -> @babel-preset-react

  

同時需要修改.babelrc配置,相當麻煩

方法三、使用babel-plugin-transform-decorators-legacy, 安裝並新增到.babelrc即可, 但需要注意的是必須將其放在其他外掛之前。

方法四、在create-react-app中使用,需要eject或者使用react-app-rewired-mobx

  1. 使用eject時 ($ npm run eject),是將專案的配置檔案全部暴露出來,注意該操作不可逆,然後再使用方法二或者方法三進行配置

  2. 使用react-app-rewired-mobx是為了避免eject專案, 安裝模組後在專案根目錄新建檔案config-overrides.js

1 const rewireMobX = require('react-app-rewire-mobx');
2 
3 /* config-overrides.js */
4 module.exports = function override(config, env) {
5   config = rewireMobX(config, env);
6   return config;
7 }

 

綜合以上方法,顯而易見方法三最簡單而且不易出錯。

 

二、修改業務程式碼

  1. 根元件不變

 1 import React from 'react';
 2 import appState from './store';
 3 import Todo from "./components/Todo";
 4 
 5 export default class App extends React.Component {
 6   render() {
 7     return (
 8       <div className='app'>
 9         <Todo appState={appState}/>
10       </div>
11     )
12   }
13 }

  2 . 修改store

 1 import {observable, action } from 'mobx'
 2 
  // 常量改成類 3 class AppState {
   // 裝飾器@
4 @observable timer = 0 5 6 @action 7 resetTimer() { 8 this.timer = 0; 9 } 10 11 @action.bound 12 increase() { 13 console.log('increase') 14 this.timer++; 15 } 16 } 17 // 將類例項化,後再暴露, 也可以先匯出再在元件使用時再例項化 18 const appState = new AppState()
  // 外部呼叫類的方法
19 setInterval(appState.increase, 1000) 20 21 export default appState;

 

  3 . 修改子元件,(將observer改成@observer放在類的前面即可)

 1 import React, {Component} from 'react';
 2 import { observer } from 'mobx-react';
 3 
 4 // 裝飾器方式@
 5 @observer
 6 class TodoList extends Component {
 7 
 8   constructor(props) {
 9     super(props);
10   }
11   // 該繫結方式屬於ES7,需要新增預設babel-preset-stage-2
12   _resetTimer = ()=> {
13     this.props.appState.resetTimer()
14   }
15   _increase = () => {
16     this.props.appState.increase()
17   }
18 
19   render() {
20     return (
21       <div>
22         <h2>TodoList</h2>
23         <p>{this.props.appState.timer}</p>
24         <button onClick={this._resetTimer}>復位</button>
25         <button onClick={this._increase}>增加</button>
26       </div>
27     );
28   }
29 }
30 
31 // 直接匯出類元件
32 export default TodoList;

 

修改完畢,專案正常執行。