MobX 是一個經過戰火洗禮的庫,它通過透明的函數響應式編程使得狀態管理變得簡單和可擴展。
React 和 MobX 是一對強力組合。React 通過提供機制把應用狀態轉換爲可渲染組件樹並對其進行渲染。而MobX提供機制來存儲和更新應用狀態供 React 使用。
一、搭建環境依賴
安裝mobx
npm install mobx mobx-react --save
或在瀏覽器上使用cdn
https://unpkg.com/mobx/lib/mobx.umd.js
https://cdnjs.com/libraries/mobx
二、啓用裝飾器語法:
大多數人使用mobx都會選擇使用裝飾器語法(你也可以選擇不使用裝飾器,則無需啓用裝飾器)。
使用裝飾器語法的優勢:
- 樣板文件最小化,聲明式代碼。
- 易於使用和閱讀。大多數 MobX 用戶都在使用。
裝飾器語法需要在es7或者在typescript中使用,如果你的環境不支持裝飾器,需要手動開啓開啓裝飾器語法。
1、安裝裝飾器所需依賴
npm install @babel/plugin-proposal-decorators --save-dev // 安裝在本地即可
2、釋放配置文件
npm run eject
如果出錯,執行以下命令,再次執行釋放配置文件:
git add .
git commit -am "msg"
3、修改package.json中的babel配置
"babel": {
"presets": [
"react-app"
],
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
]
]
}
到此已經配置完成。
三、基本使用
1、定義狀態
使用裝飾器:
import {action, observable, computed} from 'mobx';
class AppState {
@observable count = 0;
@computed get countText(){ // 計算值,當運算值中的其中一個值發生變化時都會重新計算
return '數值:' + this.count
}
@action.bound addCount(){ // 定義一個action,該action每次爲count+1。 添加bound修飾綁定對象,可保證this指向永遠正確的
this.count++
}
}
export default new AppState(); // 實例化當前類並導出
不使用裝飾器:
import {action, observable, computed, decorate} from 'mobx'; // 注意導入decorate
class AppState {
count = 0;
get countText(){
return '數值:' + this.count
}
addCount(){ // 定義一個action,該action每次爲count+1
this.count++
}
}
decorate(SppState,{
count: observable,
countText: computed,
addCount: action.bound // 添加bound修飾綁定對象,可保證this指向永遠正確的
})
export default new AppState(); // 實例化當前類並導出
需要使用 decorate
工具,decorate
接受兩個參數,第一個是目標對象,第二個參數爲裝飾器屬性參數
2、創建視圖
使用裝飾器
import {observer} from 'mobx-react'
@observer
class Page extends React.Component {
render() {
return (
<div>
<button onClick={this.props.appState.addCount}>添加</button> // 如果定義action時沒有使用bound修飾綁定對象,則需要使用匿名函數執行調用
當前數量:{this.props.appState.count}
</div>
)
}
}
export default Page;
不使用裝飾器
import {observer} from 'mobx-react'
function Page(props) {
return (
<div>
<button onClick={this.props.appState.addCount}>添加</button> // 如果定義action時沒有使用bound修飾綁定對象,則需要使用匿名函數執行調用
當前數量:{props.appState.count}
</div>
)
}
export default observer(Page); // 使其可觀察並導出
3、綁定appState到視圖組件上
import appState from './store/index' // 路徑根據實際情況而定
import Timer from './pages/Timer' // 導入視圖組件
function App() {
return (
<div>
<Timer appState={appState}></Timer> // 通過props傳遞
</div>
);
}
到此一個簡單的示例已經完成了!
三、使用 Provider、inject 工具
接着上面示例,我們給視圖組件傳遞store時,需在組件上傳遞props,目前看似無所謂,但是,如果組件多了,我們需要給給個組件都寫上同樣的props,比較麻煩,不易維護,不美觀。我們可以通過引入Provider、inject解決此類問題。
1、Provider:
Provider是一個組件,一般包裹在左右視圖組件的最外層,以實現所有組件的全局context,在所需組件裏可以通過inject獲取store。
import {Provider} from 'mobx-react';
import appState from 'store/index'; // 引入store
function App() {
return (
<Provider store={appState}> // 掛載全局store
<Timer></Timer>
</Provider>
);
}
mobx是可以拆分爲多個store的,那麼多個store如何掛載全局呢?
import {Provider} from 'mobx-react';
import {appState,appState2,appState3} as stores from 'store/index'; // 引入多個store
function App() {
return (
<Provider {...stores}> // 掛載全局store
<Timer></Timer>
</Provider>
);
}
2、inject
inject用於注入store, 在Provider包裹下的視圖組件可以通過@inject('store')的方式注入。
@inject('store') // 按照掛載時的名稱進行注入
class Page extends React.Component {...}
還可以注入多個store
@inject('store','store2','store3') // 注入多個store
class Page extends React.Component {...}
注入後,組件內可以通過 this.props.store的方式獲得狀態。
MobX中文文檔:https://cn.mobx.js.org/
注:個人筆記,不作標準答案,僅供參考。