摘要:一其實是一個比較輕便的可擴展的狀態(tài)管理工具,是一個由以及一些其他團隊的人共同維護的開源項目。當應用公共狀態(tài)的組件在狀態(tài)發(fā)生變化的時候,會自動完成與狀態(tài)相關的所有事情,例如自動更新自動緩存數(shù)據(jù),自動通知等。
一、MobX
MobX其實是一個比較輕便的可擴展的狀態(tài)管理工具,是一個由Facebook以及一些其他團隊的人共同維護的開源項目。 當應用公共狀態(tài)的組件在狀態(tài)發(fā)生變化的時候,會自動完成與狀態(tài)相關的所有事情,例如自動更新View,自動緩存數(shù)據(jù),自動通知server等。 例如React的體系,react + redux + react-redux + redux-saga, view層觸發(fā)一個action,中間件會將這個動作進行dispatch,然后reducer執(zhí)行相應的更新狀態(tài)方法,使得store的狀態(tài)更新。 MobX官方推薦與React搭配使用,來存儲和更新應用狀態(tài),所以最好搭配mobx-react中間件使用: 原理: 1、React的render是將存儲的狀態(tài)轉化為樹狀結構來渲染組件的方法; Mobx是用來存儲和更新狀態(tài)的工具; 2、React使用的方法是采用虛擬Dom來進行view視圖的緩存,來減少繁瑣的Dom更新 而Mobx則通過一個虛擬的狀態(tài)依賴圖表來讓react組件和應用狀態(tài)同步化來減少不必要的狀態(tài)來更新組件的二、MobX與其他狀態(tài)管理工具的區(qū)別
1、對比Redux conponent-->dispatch(action)-->reducer-->subscribe-->getState-->component 對比React-Redux component-->actionCreator(data)-->reducer-->component 這里的reducer在MobX里都給了action,直接通過action來更改狀態(tài),不需要reducer來操作state了,也不需關注reducer純不純了 2、對比Vuex component-->dispatch(action)-->mutation--(mutate)-->state-->component vuex中提出了同步mutation和異步action,現(xiàn)在mobx也無需mutaiton,但借鑒了computed這個純函數(shù)。 相比這兩個工具,MobX內置了數(shù)據(jù)變化監(jiān)聽機制,使得在實際應用的時候一切都是那么的順其自然。三、MobX核心模塊
MobX的數(shù)據(jù)驅動解構: action--(update)-->state--(update)-->computed--(trigger)-->reaction MobX與decorater語法結合(注解形式@)結合起來用比較優(yōu)雅,也算是MobX的一大亮點吧!Observable
是被觀察著和觀察者的概念,你也可以理解為生產(chǎn)者和消費者的概念 @observable/Observable 方法將對象的所有屬性重新克隆成新對象,并將克隆對象轉變成可觀察的。 @observer就是在你訂閱觀察的對象的地方添加注釋來監(jiān)聽對象的更新 Observable 方法的值可以是如下類型: 1、object(原型是Object): Observable方法將該對象克隆成新對象并將屬性轉變成可觀察的; 但是后添加的屬性不會變?yōu)榭捎^察的,需要用到set或者extendObservable; eg: @observable car = {color: red; name: "Infinity"} 注:這也其實是extendObservable(this,{ car: {color: red; name: "Infinity"} })的語法糖 向對象中添加屬性: extendObservable(car, {price: "300w"}) 2、Array:Observable會創(chuàng)建一個類數(shù)組對象來代替真正的數(shù)組,并且支持所有的原生方法, 但是sort和reverse有所不同,這里的被觀察的數(shù)組對象的這兩個方法,是不會改變數(shù)組本身,而是一個拷貝的數(shù)組; 3、Es6的Map:創(chuàng)建一個動態(tài)建的observable映射,可以對特定項的更改做出反應等;會返回一個新的Observable Map 4、object(有自身的原型對象):這種情況需要使用observable.box(value)來管理這樣的值 通過box這個箱子來存這些值,并使用.get()用來獲取當前值,采用.set(newValue)來更新值。 eg: const carName = observable.box("Infinity"); console.log(carName.get()); carName.set("ofo");Computed
是在定義相關的一些數(shù)據(jù)發(fā)生變化的時候自動更新的值,通過@computed來修飾使用; 注意:computed修飾的是一個狀態(tài),狀態(tài)不能重復聲明,只有參與計算的值發(fā)生改變才會觸發(fā)computed 例如我需要對數(shù)組進行篩選: @observable numbersArr = [99, 80, 79, 68, 2, 43, 1, 23]; 一、getter eg: // 篩選數(shù)組中乘2并大于50的數(shù) @computed get computedNumbers() { return this.numbersArr.filter((item) => { return item * 2 > 50; }).join(" "); } 然后在組件內進行調用:Action{this.props.store.computedNumbers}二、setter set computedBumbers(value) { this.numbersArr = [99, 80, 79, 68, 2, 43, 1, 23]; } // set方式可以使得數(shù)據(jù)進行逆推導 將數(shù)據(jù)按照既定的方式進行復原 eg: @observable length = 2; @computed get squared() { return this.length * this.length; } set squared(value) { this.length = Math.sqrt(value); } 注:這與autorun還有點區(qū)別,如果有一個函數(shù)應該自動運行(例如只是為了達到某種效果/功能),但不會產(chǎn)生一個新的值,那就使用autorun,但是一般這種情況比較少
比起官方說的“動作”,我更愿意稱為是“行為”,mobx的action吸收了redux和vuex的數(shù)據(jù)處理的復雜邏輯 用來修改狀態(tài),不同于Computed eg: component: sendInfo = () => { const username = this.name.value; const pwd = this.pwd.value; if (!username || !pwd) { return; } // 調接口 this.props.testDecStore.handleGetUserInfo(); }; store: // 四、異步數(shù)據(jù)獲取 @action handleGetUserInfo() { this.sendCount++; testDecService.getUserInfo().then((data) => { this.userInfo = data; }) }Autorun
這個函數(shù)類似computed,是通過對狀態(tài)的更新做出反應,但是不同于computed。 computed創(chuàng)建的函數(shù),是有自己的觀察者的,而autorun是只有它的依賴關系改變時才會重新計算, 否則它的值被認為是不相干的。正如官方所說是比較適合log打印日志,持久化更新UI的代碼,而不是用來產(chǎn)生新的值 接收的參數(shù): 1,對象, 2、delay: 函數(shù)延遲執(zhí)行時間,例如節(jié)流去抖 3、name: 4、onError: 用來處理reaction的錯誤 5、scheduler: 設置自定義調度器以決定如何調度autorun函數(shù)的重新運行 eg: autorun(() => { // do something }, { onError(e) { alert("error") } }) 實例: autorun(() => { this.myname = `my name is ${this.firstName} ${this.lastName}`; }); changeName = () => { this.firstName = `Alice${new Date().getTime()}`; this.lastName = `Thomas${new Date().getTime()}`; };測試autorun 開始只要firstname和lastname發(fā)生變化都會更新dom{this.myname}
但是,如果僅僅想要在被觀察的變量有變化的時候觸發(fā),而不是立即執(zhí)行autorun,那么我們可以用到reaction了;
ReactionReaction是在初次數(shù)據(jù)變化后才會觸發(fā)四、Mobx-react核心概念 Observer
是mobx-react包多帶帶提供的 Observer是用來將React組建轉變成響應式的組件,內部通過mobx.autorun包裝了組件的 render函數(shù),來確保store的數(shù)據(jù)更新時來刷新組件 @observer 是observer(class ***{})的注解形式,用來觀察組件, 高階組件 @observer class Test extends React.Component{} 無狀態(tài)組件 const Test = observer(() =>Providertest) 使用inject組件連接提供的sotres,他會使得stores可以作為組件的props調用 eg: @inject("testStore") @observer class Test extends React.Component{}
Provider函數(shù)為connect函數(shù)提供store參數(shù),本身connect函數(shù)就是用來連接視圖和數(shù)據(jù)層的方法。 在跟組件外層包一層provider,使得所有的子組件默認都可以拿到state 使用: import { Provider } from "mobx-react"; import store from "../stores";inject...
引入數(shù)據(jù)的方式,@inject(stores); 使得數(shù)據(jù)被自動保存在組件的this.props中componentWillReact
mobx-react新增的生命周期鉤子,當組件重新render的時候會被觸發(fā),但在初始渲染前是不會被觸發(fā)的onError
mobx-react提供的錯誤鉤子函數(shù)來收集錯誤 用法: import { onError } from "mobx-react"; onError((error) => { consol.log(error); })五、MobX源碼解讀 六、MobX使用注意
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/95993.html
摘要:我現(xiàn)在寫的這些是為了解決和這兩個狀態(tài)管理庫之間的困惑。這甚至是危險的,因為這部分人將無法體驗和這些庫所要解決的問題。這肯定是要第一時間解決的問題。函數(shù)式編程是不斷上升的范式,但對于大部分開發(fā)者來說是新奇的。規(guī)模持續(xù)增長的應 原文地址:Redux or MobX: An attempt to dissolve the Confusion 原文作者:rwieruch 我在去年大量的使用...
摘要:原理分析的核心就是通過觀察某一個變量,當該變量產(chǎn)生變化時,對應的內的回調函數(shù)就會發(fā)生變化。回調函數(shù)若依賴外部環(huán)境,則無法進行收集很好理解,的回調函數(shù)在預執(zhí)行的時候無法到達那一行代碼,所以收集不到。 Mobx解決的問題 傳統(tǒng)React使用的數(shù)據(jù)管理庫為Redux。Redux要解決的問題是統(tǒng)一數(shù)據(jù)流,數(shù)據(jù)流完全可控并可追蹤。要實現(xiàn)該目標,便需要進行相關的約束。Redux由此引出了dispa...
摘要:一步,兩步,三步四步五步,就這樣到達了人生的巔峰傳統(tǒng)前端生態(tài)初級不使用打包中間處理工具,手工處理圖片等資源掌握以下知識點基礎結構,基礎樣式,基礎語法框架,系列插件框架,等基礎插件,等其他移動端適配,瀏覽器兼容,瀏覽器調試等恭喜完成新手村修 一步,兩步,三步四步五步,就這樣到達了人生的巔峰~ 傳統(tǒng)前端生態(tài)-初級 不使用打包、中間處理工具,手工處理js、css、圖片等資源 掌握以下知識點:...
閱讀 2866·2021-11-11 10:58
閱讀 1920·2021-10-11 10:59
閱讀 3489·2019-08-29 16:23
閱讀 2324·2019-08-29 11:11
閱讀 2785·2019-08-28 17:59
閱讀 3838·2019-08-27 10:56
閱讀 2049·2019-08-23 18:37
閱讀 3111·2019-08-23 16:53