mobx 的設計思想我總結以後,主要有如下兩點:javascript
mobx 不一樣於 redux 的單一數據源的統一管理,它能夠有多個 store, 爲了便於維護 ,每個 store 都是一個類,這樣便於維護和擴展;php
同時,爲了使數據能夠自動更新,使用了響應式編程(異步數據流), 它使用了觀察者模式和 裝飾器模式,將 state 包裹成observable; 當state 有改變時(本身改變或是 action 觸發), 就會相應的去更新由這個state 推導出來的 computed value 以及 reaction;(數據的更新主要由裝飾器模式中的對類的修改 );vue
它的工做流大體是這樣子:java
mobx 與redux 同樣也是單向數據流,核心概念是 state,computed value,reaction,action 等。它們的大概功能爲:react
state: 包裹爲 observable 的 的數據;編程
computed values: 從當前 state 中計算出的值,相似與 vue 中的computed;redux
reactions: 是當 state 改變時須要自動發生的反作用。好比打印到控制檯、網絡請求、遞增地更新 React 組件樹以修補 DOM 等等;不會產生值,常見 api 有 autorun, reaction, observe (針對性觀察新舊值)等;後端
action: 是一段能夠改變狀態的代碼。用戶事件、後端數據推送、預約事件、等等。一般使用 action 統一對 state 修改,而不是對自身修改;api
這樣聽可能有一點抽象, 以表格爲例:在電子表格中,有值的單元格都是 observable state;公式和圖標是可從數據單元格和其餘公式推導出的computed value;在屏幕上繪製數據單元格、公式的輸出結果就是一個 reactions;對數據單元格或公式的修改就是一次action;性能優化
這裏用一個栗子介紹:
class Person { // 定義狀態 [@observable] firstName = "huang"; [@observable] lastName = "yuan"; [@observable] nickName; @computed get fullName() { return this.firstName + " " + this.lastName; } @action.bound increment() { this.firstName = "zhang"; } } decorate{ } const coolGirl = new Person(); // reactions:打印日誌 autorun(() => { console.log( person.nickName ? person.nickName : person.fullName ) }); const ProfileView = observer(props => { if (props.person.nickName) return <div>{props.person.nickName}</div> else return <div>{props.person.fullName}</div> }); // action setTimeout(() => coolGirl.nickName = "yuanzhendashi", 5000); setIimeout(coolGirl.increment, 1000); React.render(<ProfileView person={coolGirl} />), document.body);
這是一個很簡單的栗子,展現了mobx 的基本使用,主要分爲這幾個步驟;
這是一個最簡單的例子,展現了 Mobx 主要的代碼組成:定義狀態 -> 註冊反應 -> 修改狀態 -> 執行反應。
主要跟你們說說,在與現有的技術棧或應用結合時,Mobx 生態有哪些最佳實踐和優質的庫。
當與 React 結合時,使用了mobox-react 庫來處理 state 變化和view 更新的綁定在用法上,主要分爲四個步驟:
一、 使用Provide組件用來包裹最外層組件節點,傳入 store 經過 context 傳遞給後代組件;
2 . 經過 @observer 將 React 組件轉化成響應式組件;mobx 用 autorun 包裝了組件的 render 函數以確保任何組件渲染中使用的數據變化時均可以強制刷新組件;
使用 @inject 給組件注入其須要的store,放置於 props 上;
觀察並使用store 中的observable 數據
以下面代碼
// 以 context 的形式傳入store import { Provider } from 'mobx-react' <Provider store={coolGirl}> <ProfileView/> </Provider> // 使用狀態 import * as React from 'react' import { inject, observer } from 'mobx-react' @inject('store') // 若是是以 context 傳入的必需要 @inject,不然不須要。 @observer **export de**fault class ProfileView extends React.Component { render () { return ( <div> 個人姓名:{this.props.store.fullName} </div> ) } }
能夠看出,使用起來很是簡便;
儘量多地使用小組件;@observer 組件會追蹤 render 方法中全部的可觀測的值,當任何一個值變化的時候,都會從新渲染,因此組件越小,從新渲染的變化就越小。
在專用的組件中渲染列表;
晚一點使用間接引用值;使用 mobx-react 時,推薦儘量晚的使用間接引用值。 這是由於當使用 observable 間接引用值時 MobX 會自動從新渲染組件。 若是間接引用值發生在組件樹的層級越深,那麼須要從新渲染的組件就越少;
快的: <DisplayName person={person} /> 慢的: <DisplayName name={person.name} />
對於autorun 和reaction,每次變化的準備時間和結束時間爲0.5 ~ 1ms。因此,可能不適合跟蹤頻繁變化的狀態;
減小渲染次數: 使用 action 觸發狀態更新;
vi設計http://www.maiqicn.com 辦公資源網站大全https://www.wode007.com
內存/mobx-state-tree
綜上,使用mobx-react , 會有這些優缺點: