摘要:有了這個(gè),下一步就是開始對變化作出反應(yīng)。請注意,此延遲通知僅適用于當(dāng)前函數(shù)范圍中的。最快的方法是提供功能。只有當(dāng)返回的數(shù)據(jù)發(fā)生變化時(shí),才會(huì)執(zhí)行副作用。最棒的部分是它會(huì)在運(yùn)行后自動(dòng)處理副作用。構(gòu)建可觀察數(shù)據(jù)掌握數(shù)據(jù)變更方法高階應(yīng)用實(shí)例
在上一部分中,我們研究了如何設(shè)置MobX狀態(tài)樹并使其可觀察。 有了這個(gè),下一步就是開始對變化作出反應(yīng)。 坦率地說,這就是有趣的開始!
MobX保證只要您的響應(yīng)數(shù)據(jù)圖發(fā)生變化,依賴于可觀察屬性的部分就會(huì)自動(dòng)同步。 這意味著您現(xiàn)在可以專注于對變化做出反應(yīng)并引起的副作用,而不是擔(dān)心數(shù)據(jù)同步。
讓我們深入研究一下可以引起副作用的各種方法。
使用@action作為入口點(diǎn)默認(rèn)情況下,當(dāng)您修改observable時(shí),MobX將檢測并保持其他依賴的可觀察對象同步。 這是同步發(fā)生的。 但是,有時(shí)您可能希望在同一方法中修改多個(gè)observable。 這可能會(huì)導(dǎo)致多個(gè)通知被觸發(fā),甚至可能會(huì)降低您的應(yīng)用速度。
更好的方法是action()中包裝要調(diào)用的方法。 這會(huì)在您的方法周圍創(chuàng)建一個(gè)事務(wù)邊界,并且所有受影響的observable將在您執(zhí)行操作后保持同步。 請注意,此延遲通知僅適用于當(dāng)前函數(shù)范圍中的observable。 如果您具有修改更多可觀察對象的異步操作,則必須將它們包裝在runInAction()中。
class Person { @observable firstName; @observable lastName; // 因?yàn)槲覀冊贎action中包裝了此方法,所以只有在changeName()成功執(zhí)行后,fullName才會(huì)更改 @action changeName(first, last) { this.firstName = first; this.lastName = last; } @computed get fullName() { return `${this.firstName}, ${this.lastName}`; } } const p = new Person(); p.changeName("Pavan", "Podila");
Actions是改變Store的切入點(diǎn)。 通過使用Actions,您可以將多個(gè)observable更新為原子操作。
盡可能避免直接從外部操縱observable并公開@action方法為你做這個(gè)改變。 實(shí)際上,可以通過設(shè)置useStrict(true)來強(qiáng)制執(zhí)行此操作。使用@autorun觸發(fā)副作用
MobX確保可觀察圖形始終保持一致。 但如果這個(gè)世界只是關(guān)于可觀察的東西,那就不好玩了。 我們需要他們的同行:觀察者使事情變得有趣。
實(shí)際上,UI是mobx store的美化觀察者。 使用mobx-react,您將獲得一個(gè)綁定庫,使您的React組件可以觀察存儲(chǔ)并在存儲(chǔ)更改時(shí)自動(dòng)呈現(xiàn)。
但是,UI不是系統(tǒng)中唯一的觀察者。 您可以向store添加更多觀察者以執(zhí)行各種有趣的事情。 一個(gè)非常基本的觀察者可能是一個(gè)控制臺(tái)記錄器,它只是在可觀察的變化時(shí)將當(dāng)前值記錄到控制臺(tái)。
通過autorun,我們可以非常輕松地設(shè)置這些觀察者。 最快的方法是提供autorun功能。 MobX會(huì)自動(dòng)跟蹤您在此函數(shù)中使用的任何可觀察對象。 每當(dāng)它們改變時(shí),你的功能都會(huì)重新執(zhí)行(也就是自動(dòng)運(yùn)行)!
class Person { @observable firstName = "None"; @observable lastName = "None"; constructor() { // A simple console-logger autorun(()=>{ console.log(`Name changed: ${this.firstName}, ${this.lastName}`); }); // 這里會(huì)導(dǎo)致autorun()運(yùn)行 this.firstName = "Mob"; // autorun()再一次運(yùn)行 this.lastName = "X"; } } // Will log: Name changed: None, None // Will log: Name changed: Mob, None // Will log: Name changed: Mob, X
正如您在上面的日志中所看到的,自動(dòng)運(yùn)行將立即運(yùn)行,并且每次跟蹤的可觀察量發(fā)生變化時(shí)也會(huì)運(yùn)行。 如果您不想立即運(yùn)行,而是僅在發(fā)生更改時(shí)運(yùn)行,該怎么辦? 請繼續(xù)閱讀。
與autorun相比,reaction提供了更細(xì)粒度的控制。 首先,它們不會(huì)立即運(yùn)行并等待對跟蹤的可觀察量的第一次更改。 API也與autorun略有不同。 在最簡單的版本中,您提供兩個(gè)輸入?yún)?shù):
reaction(()=> data, data => { /* side effect */})
第一個(gè)函數(shù)(跟蹤函數(shù) tracking function)應(yīng)該返回將用于跟蹤的數(shù)據(jù)。 然后將該數(shù)據(jù)傳遞給第二個(gè)函數(shù)(效果函數(shù) effect function)。 不跟蹤效果函數(shù),您可以在此處使用其他可觀察對象。
默認(rèn)情況下,reaction將不會(huì)在第一次運(yùn)行,并將等待追蹤函數(shù)的變更。 只有當(dāng)tracking function返回的數(shù)據(jù)發(fā)生變化時(shí),才會(huì)執(zhí)行副作用。 通過將原始自動(dòng)運(yùn)行分解為tracking function +effect function,您可以更好地控制實(shí)際導(dǎo)致副作用的內(nèi)容。
import {reaction} from "mobx"; class Router { @observable page = "main"; setupNavigation() { reaction(()=>this.page, (page)=>{ switch(page) { case "main": this.navigateToUrl("/"); break; case "profile": this.navigateToUrl("/profile"); break; case "admin": this.navigateToUrl("/admin"); break; } }); } navigateToUrl(url) { /* ... */ } }
在上面的示例中,我在加載“main”頁面時(shí)不需要導(dǎo)航。 一個(gè)reaction使用的完美案例。 僅當(dāng)路由器的頁面屬性發(fā)生更改時(shí),才會(huì)導(dǎo)航到特定URL。
以上是一個(gè)非常簡單的路由器,具有固定的頁面集。 您可以通過向URL添加頁面地圖來使其更具可擴(kuò)展性。 使用這種方法,路由(使用URL更改)會(huì)成為更改Store某些屬性的副作用。
使用when觸發(fā)一次性的副作用autorun和reaction是持續(xù)的副作用。 初始化應(yīng)用程序時(shí),您將創(chuàng)建此類副作用,并期望它們在應(yīng)用程序的生命周期內(nèi)運(yùn)行。
我之前沒有提到的一件事是這兩個(gè)函數(shù)都返回一個(gè)處理器函數(shù)。 您可以隨時(shí)調(diào)用該處理器函數(shù)并取消副作用。
const disposer = autorun(()=>{ /* side-effects based on tracked observables */ }); // .... At a later time disposer(); // Cancel the autorun
現(xiàn)在我們構(gòu)建的應(yīng)用程序有各種用例。 您可能希望某些副作用僅在您到達(dá)應(yīng)用程序中的某個(gè)點(diǎn)時(shí)運(yùn)行。 此外,您可能希望這些副作用只運(yùn)行一次,然后再也不會(huì)運(yùn)行。
讓我們舉一個(gè)具體的例子:比如說,當(dāng)用戶到達(dá)應(yīng)用程序中的某個(gè)里程碑時(shí),您希望向用戶顯示一條消息。 此里程碑僅對任何用戶發(fā)生一次,因此您不希望設(shè)置持續(xù)運(yùn)行的副作用,如autorun或reaction。 現(xiàn)在是時(shí)候拿出when 這個(gè)API來完成這項(xiàng)工作了。
當(dāng)拿出兩個(gè)參數(shù)時(shí),就像reaction一樣。 第一個(gè)(跟蹤器函數(shù))應(yīng)該返回一個(gè)布爾值。 當(dāng)這變?yōu)檎鏁r(shí),它將運(yùn)行效果函數(shù),第二個(gè)參數(shù)為when。 最棒的部分是它會(huì)在運(yùn)行后自動(dòng)處理副作用。 因此,無需跟蹤處理器并手動(dòng)調(diào)用它。
when(()=>this.reachedMilestone, ()=>{ this.showMessage({ title: "Congratulations", message: "You did it!" }); })
到目前為止,我們已經(jīng)看到了各種技術(shù)來跟蹤對象圖上的變化,并對這些變化做出反應(yīng)。 MobX提高了抽象級(jí)別,以便我們可以在更高級(jí)別進(jìn)行思考,而不必?fù)?dān)心跟蹤和對變化做出反應(yīng)的意外復(fù)雜性。
我們現(xiàn)在有了一個(gè)基礎(chǔ),可以構(gòu)建依賴于域模型更改的強(qiáng)大系統(tǒng)。 通過將域模型之外的所有內(nèi)容視為副作用,我們可以提供視覺反饋(UI)并執(zhí)行許多其他活動(dòng),如監(jiān)控,分析,日志記錄等。
Part 1 - 構(gòu)建可觀察數(shù)據(jù)
Part 2 - 掌握數(shù)據(jù)變更方法
Part 3 - 高階應(yīng)用實(shí)例
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/97418.html
摘要:高效的模式提供了一種簡單而強(qiáng)大的方法來管理客戶端狀態(tài)。允許屬性本身可觀察,但不允許其任何子節(jié)點(diǎn)。默認(rèn)情況下,僅將引用更改視為更改。構(gòu)建可觀察數(shù)據(jù)掌握數(shù)據(jù)變更方法高階應(yīng)用實(shí)例 起因 很早之前看到的一篇關(guān)于mobx的文章,之前記得是有人翻譯過的,但是怎么找都找不到,故花了點(diǎn)時(shí)間通過自己那半桶水的英文水平,加上Google翻譯一下,對于初學(xué)者,以及mobx的開發(fā)者提供些許幫助。 這里針對已經(jīng)...
摘要:當(dāng)樹變異時(shí),連接的部分將作出反應(yīng)并更新以反映變化。接下來,我們必須對這些行動(dòng)狀態(tài)發(fā)生的變化作出反應(yīng)。這可用于將工作流轉(zhuǎn)換為其他狀態(tài)。將其視為產(chǎn)生價(jià)值的可觀察物。構(gòu)建可觀察數(shù)據(jù)掌握數(shù)據(jù)變更方法高階應(yīng)用實(shí)例 前兩部分側(cè)重于MobX的基本構(gòu)建塊。 有了這些塊,我們現(xiàn)在可以通過MobX的角度開始解決一些真實(shí)場景。 這篇文章將是一系列應(yīng)用我們迄今為止所見概念的例子。 當(dāng)然,這不是一個(gè)詳盡的清單,...
摘要:最簡單的情況張三的存貸這里我們創(chuàng)建了實(shí)例探長實(shí)例觀察員這個(gè)示例和我們之前在首篇文章用故事解讀源碼一中所用示例是一致的。 ================前言=================== 初衷:以系列故事的方式展現(xiàn) MobX 源碼邏輯,盡可能以易懂的方式講解源碼; 本系列文章: 《【用故事解讀 MobX源碼(一)】 autorun》 《【用故事解讀 MobX源碼(二)】...
摘要:前言初衷以系列故事的方式展現(xiàn)源碼邏輯,盡可能以易懂的方式講解源碼本系列文章用故事解讀源碼一用故事解讀源碼二用故事解讀源碼三用故事解讀源碼四裝飾器和用故事解讀源碼五文章編排每篇文章分成兩大段,第一大段以簡單的偵探系列故事的形式講解所涉及人物場 ================前言=================== 初衷:以系列故事的方式展現(xiàn) MobX 源碼邏輯,盡可能以易懂的方式...
摘要:也就是說不應(yīng)該有公開的,所有都應(yīng)該是私有的,只能有公開的。允許使用方法設(shè)置監(jiān)聽函數(shù),一旦發(fā)生變化,就自動(dòng)執(zhí)行這個(gè)函數(shù)。用一個(gè)叫做的純函數(shù)來處理事件。可以通過得到當(dāng)前狀態(tài)。在中,同步的表現(xiàn)就是發(fā)出以后,立即算出。 這篇文章試著聊明白這一堆看起來挺復(fù)雜的東西。在聊之前,大家要始終記得一句話:一切前端概念,都是紙老虎。 不管是Vue,還是 React,都需要管理狀態(tài)(state),比如組件之...
閱讀 3255·2021-09-23 11:55
閱讀 2587·2021-09-13 10:33
閱讀 1656·2019-08-30 15:54
閱讀 3085·2019-08-30 15:54
閱讀 2357·2019-08-30 10:59
閱讀 2361·2019-08-29 17:08
閱讀 1793·2019-08-29 13:16
閱讀 3582·2019-08-26 12:25