国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
observable
autorun
computed
更多!
首頁 web前端 js教程 如何使用MOBX管理JavaScript應(yīng)用程序狀態(tài)

如何使用MOBX管理JavaScript應(yīng)用程序狀態(tài)

Feb 17, 2025 am 08:57 AM

How to Manage Your JavaScript Application State with MobX

How to Manage Your JavaScript Application State with MobX

本文由Michel Weststrate和Aaron Boyer同行評審。感謝所有SitePoint的同行評審員,使SitePoint的內(nèi)容盡善盡美!

如果您曾經(jīng)使用jQuery編寫過比非常簡單的應(yīng)用程序更復(fù)雜的應(yīng)用程序,您可能遇到過保持UI不同部分同步的問題。通常,數(shù)據(jù)的更改需要反映在多個位置,并且隨著應(yīng)用程序的增長,您可能會發(fā)現(xiàn)自己陷入困境。為了控制這種混亂,通常使用事件來讓應(yīng)用程序的不同部分知道何時發(fā)生了更改。

那么,您今天是如何管理應(yīng)用程序狀態(tài)的呢?我要冒昧地說,您過度訂閱了更改。沒錯。我什至不認識你,但我就要指出來。如果您沒有過度訂閱,那么我敢肯定您工作太努力了。

當(dāng)然,除非您使用MobX……

關(guān)鍵要點

  • 利用MobX簡化狀態(tài)管理:利用MobX通過可觀察對象有效地管理應(yīng)用程序狀態(tài),減少在Redux等其他狀態(tài)管理庫中發(fā)現(xiàn)的復(fù)雜性和樣板代碼。
  • MobX自動更新:實現(xiàn)MobX的autorun功能,以自動響應(yīng)狀態(tài)更改更新UI組件,無需手動事件處理,從而簡化整個應(yīng)用程序的同步過程。
  • 使用計算值增強性能:使用MobX的計算值從狀態(tài)派生數(shù)據(jù),確保僅在必要時重新渲染組件,從而提高整體應(yīng)用程序性能。
  • MobX易于上手:通過將標(biāo)準(zhǔn)對象轉(zhuǎn)換為可觀察對象,將MobX無縫集成到現(xiàn)有的JavaScript應(yīng)用程序中,允許逐步采用,而無需完全重寫。
  • 利用MobX操作進行事務(wù)性修改:應(yīng)用MobX操作將狀態(tài)修改封裝在事務(wù)中,從而批量更新并最大限度地減少冗余渲染,從而獲得更高效、更不易出錯的代碼。

什么是“狀態(tài)”?

這是一個人物。嘿,那就是我!我有一個firstName、lastName和age。此外,如果我遇到麻煩,fullName()函數(shù)可能會出現(xiàn)。

var person = {
  firstName: 'Matt',
  lastName: 'Ruby',
  age: 37,
  fullName: function () {
    return this.firstName + ' ' + this.lastName;
  }
};

您將如何通知您的各種輸出(視圖、服務(wù)器、調(diào)試日志)對該人員的修改?您將在何時觸發(fā)這些通知?在MobX之前,我將使用觸發(fā)自定義jQuery事件或js-signals的setter。這些選項為我提供了良好的服務(wù),但是,我對它們的用法遠非細致入微。如果person對象的任何部分發(fā)生更改,我將觸發(fā)一個“changed”事件。

假設(shè)我有一段視圖代碼顯示我的名字。如果我更改了我的年齡,該視圖將更新,因為它與該person的changed事件綁定。

var person = {
  firstName: 'Matt',
  lastName: 'Ruby',
  age: 37,
  fullName: function () {
    return this.firstName + ' ' + this.lastName;
  }
};

我們?nèi)绾问站o這種過度觸發(fā)?簡單。只需為每個字段設(shè)置一個setter,并為每個更改設(shè)置單獨的事件。等等——如果您想一次更改age和firstName,您可能會開始過度觸發(fā)。您必須創(chuàng)建一種方法來延遲事件觸發(fā),直到兩個更改都完成。這聽起來像工作,而我很懶……

MobX來救援

MobX是由Michel Weststrate開發(fā)的一個簡單、專注、高效且不顯眼的狀態(tài)管理庫。

來自MobX文檔:

只需對狀態(tài)執(zhí)行某些操作,MobX將確保您的應(yīng)用程序尊重這些更改。

person.events = {};

person.setData = function (data) {
  $.extend(person, data);
  $(person.events).trigger('changed');
};

$(person.events).on('changed', function () {
  console.log('first name: ' + person.firstName);
});

person.setData({age: 38});

注意到區(qū)別了嗎?mobx.observable是我所做的唯一更改。讓我們再次查看該console.log示例:

var person = mobx.observable({
  firstName: 'Matt',
  lastName: 'Ruby',
  age: 37,
  fullName: function () {
    return this.firstName + ' ' + this.lastName;
  }
});

使用autorun,MobX將只觀察已訪問的內(nèi)容。

如果您認為這很整潔,請查看以下內(nèi)容:

mobx.autorun(function () {
  console.log('first name: ' + person.firstName);
});

person.age = 38; // 打印為空
person.lastName = 'RUBY!'; // 仍然為空
person.firstName = 'Matthew!'; // 此處觸發(fā)

感興趣嗎?我知道你感興趣。

MobX核心概念

observable

mobx.autorun(function () {
  console.log('Full name: ' + person.fullName);
});

person.age = 38; // 打印為空
person.lastName = 'RUBY!'; // 觸發(fā)
person.firstName = 'Matthew!'; // 也觸發(fā)

MobX可觀察對象只是對象。在這個例子中,我沒有觀察任何東西。此示例顯示了如何開始將MobX集成到您現(xiàn)有的代碼庫中。只需使用mobx.observable()mobx.extendObservable()即可開始。

autorun

var log = function(data) {
  $('#output').append('' +data+ '');
}

var person = mobx.observable({
  firstName: 'Matt',
  lastName: 'Ruby',
  age: 34
});

log(person.firstName);

person.firstName = 'Mike';
log(person.firstName);

person.firstName = 'Lissy';
log(person.firstName);

當(dāng)您的可觀察值發(fā)生變化時,您想做些什么,對吧?讓我介紹autorun(),它將在任何引用的可觀察值發(fā)生變化時觸發(fā)回調(diào)。請注意,在上面的示例中,當(dāng)age更改時,autorun()不會觸發(fā)。

computed

var person = mobx.observable({
  firstName: 'Matt',
  lastName: 'Ruby',
  age: 0
});

mobx.autorun(function () {
  log(person.firstName + ' ' + person.age);
});

// 這將打印Matt NN 10次
_.times(10, function () {
  person.age = _.random(40);
});

// 這將什么也不打印
_.times(10, function () {
  person.lastName = _.random(40);
});

看到那個fullName函數(shù)了嗎?注意它沒有參數(shù)以及get?MobX將自動為您創(chuàng)建一個計算值。這是我最喜歡的MobX功能之一。注意person.fullName有什么奇怪的地方嗎?再看一遍。這是一個函數(shù),您無需調(diào)用它就可以看到結(jié)果!通常,您將調(diào)用person.fullName()而不是person.fullName。您剛剛遇到了您的第一個JS getter。

樂趣并沒有到此結(jié)束!MobX將監(jiān)視計算值的依賴項以進行更改,并且在它們發(fā)生更改時運行。如果沒有任何更改,則將返回緩存的值。請參見下面的情況:

var person = mobx.observable({
  firstName: 'Matt',
  lastName: 'Ruby',
  age: 0,
  get fullName () {
    return this.firstName + ' ' + this.lastName;
  }
});
log(person.fullName);

person.firstName = 'Mike';
log(person.fullName);

person.firstName = 'Lissy';
log(person.fullName);

在這里您可以看到,我已經(jīng)多次命中了person.fullName計算,但是函數(shù)運行的唯一時間是當(dāng)firstName或lastName發(fā)生更改時。這是MobX可以極大地加快應(yīng)用程序速度的方法之一。

更多!

我不會再繼續(xù)重寫MobX精彩的文檔了。查看文檔以了解有關(guān)使用和創(chuàng)建可觀察對象的更多方法。

(以下內(nèi)容略去部分代碼示例和詳細解釋,保留核心內(nèi)容和結(jié)構(gòu))

將MobX投入使用

在過分枯燥之前,讓我們構(gòu)建一些東西。

這是一個簡單的非MobX示例,它將顯示每當(dāng)人員更改時人員的全名。

注意,即使我們從未更改名字,名稱也渲染了10次。您可以使用許多事件或檢查某種更改的有效負載來優(yōu)化此問題。這工作量太大了。

這是一個使用MobX構(gòu)建的相同示例:

注意,沒有事件、觸發(fā)器或on。使用MobX,您正在處理最新值以及它已更改的事實。注意它只渲染了一次嗎?這是因為我沒有更改autorun正在監(jiān)視的任何內(nèi)容。

讓我們構(gòu)建一些稍微不那么瑣碎的東西:

在這里,我們能夠編輯整個person對象并自動監(jiān)視數(shù)據(jù)輸出?,F(xiàn)在,此示例中有一些軟點,最值得注意的是輸入值與person對象不同步。讓我們解決這個問題:

我知道,你還有一個抱怨:“Ruby,你渲染過度了!”你是對的。這就是為什么許多人選擇使用React的原因。React允許您輕松地將輸出分解成可以單獨渲染的小組件。

為了完整起見,這里有一個我已優(yōu)化的jQuery示例。

我會在真實的應(yīng)用程序中做這樣的事情嗎?可能不會。如果我需要這種粒度,我隨時都會使用React。當(dāng)我在真實的應(yīng)用程序中使用MobX和jQuery時,我使用足夠細致的autorun(),以至于我沒有在每次更改時都重建整個DOM。

您已經(jīng)走到了這一步,所以這里是用React和MobX構(gòu)建的相同示例

讓我們構(gòu)建一個幻燈片放映

您將如何表示幻燈片放映的狀態(tài)?讓我們從單個幻燈片工廠開始:

我們應(yīng)該有一些東西可以聚合我們所有的幻燈片。讓我們現(xiàn)在構(gòu)建它:

幻燈片放映開始了!這更有趣,因為我們有一個可觀察的幻燈片數(shù)組,它允許我們從集合中添加和刪除幻燈片,并相應(yīng)地更新我們的UI。接下來,我們添加activeSlide計算值,該值將根據(jù)需要保持自身最新。

讓我們渲染我們的幻燈片放映。我們還沒有準(zhǔn)備好HTML輸出,所以我們只會打印到控制臺。

很酷,我們有一些幻燈片,autorun剛剛打印出了它們當(dāng)前的狀態(tài)。讓我們更改一個或兩個幻燈片:

看起來我們的autorun正在工作。如果您更改autorun正在監(jiān)視的任何內(nèi)容,它將觸發(fā)。讓我們將輸出派生從控制臺更改為HTML:

我們現(xiàn)在已經(jīng)有了這個幻燈片放映的基本顯示,但是,還沒有交互性。您不能點擊縮略圖并更改主圖像。但是,您可以輕松地使用控制臺更改圖像文本并添加幻燈片:

讓我們創(chuàng)建我們的第一個也是唯一一個操作來設(shè)置選定的幻燈片。我們將不得不通過添加以下操作來修改slideShowModelFactory

您可能會問,為什么要使用操作?好問題!MobX操作不是必需的,正如我在更改可觀察值的其他示例中所展示的那樣。

操作在幾個方面對您有所幫助。首先,所有MobX操作都在事務(wù)中運行。這意味著我們的autorun和其他MobX反應(yīng)將等待操作完成后再觸發(fā)。考慮一下。如果我嘗試在事務(wù)之外停用活動幻燈片并激活下一個幻燈片會發(fā)生什么?我們的autorun將觸發(fā)兩次。第一次運行會很尷尬,因為將沒有活動幻燈片可供顯示。

除了它們的事務(wù)性質(zhì)之外,MobX操作往往使調(diào)試更簡單。我傳遞給mobx.action的第一個可選參數(shù)是字符串“set active slide”。此字符串可以使用MobX的調(diào)試API輸出。

所以我們有我們的操作,讓我們使用jQuery連接它的用法:

就是這樣。您現(xiàn)在可以點擊縮略圖,并且活動狀態(tài)將按預(yù)期傳播。這是幻燈片放映的工作示例:

這是一個使用React的相同幻燈片放映的示例。

注意,我根本沒有更改模型?就MobX而言,React只是您數(shù)據(jù)的另一種派生,例如jQuery或控制臺。

jQuery幻燈片放映示例的警告

請注意,我沒有以任何方式優(yōu)化jQuery示例。我們在每次更改時都會破壞整個幻燈片放映DOM。通過破壞,我的意思是我們在每次點擊時都會替換幻燈片放映的所有HTML。如果您要構(gòu)建一個強大的基于jQuery的幻燈片放映,您可能會在初始渲染后調(diào)整DOM,方法是設(shè)置和刪除活動類并更改mainImagesrc屬性。

想了解更多?

如果您想了解更多關(guān)于MobX的信息,請查看下面一些其他有用的資源:

如果您有任何疑問,請在下面的評論中告訴我,或者在MobX gitter頻道中找到我。

關(guān)于使用MobX管理JavaScript應(yīng)用程序狀態(tài)的常見問題解答(FAQ)

(以下內(nèi)容略去FAQ部分,因為篇幅過長,且與核心內(nèi)容關(guān)系不大。)

以上是如何使用MOBX管理JavaScript應(yīng)用程序狀態(tài)的詳細內(nèi)容。更多信息請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻,版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機

Video Face Swap

Video Face Swap

使用我們完全免費的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

Java vs. JavaScript:清除混亂 Java vs. JavaScript:清除混亂 Jun 20, 2025 am 12:27 AM

Java和JavaScript是不同的編程語言,各自適用于不同的應(yīng)用場景。Java用于大型企業(yè)和移動應(yīng)用開發(fā),而JavaScript主要用于網(wǎng)頁開發(fā)。

JavaScript評論:簡短說明 JavaScript評論:簡短說明 Jun 19, 2025 am 12:40 AM

JavascriptconcommentsenceenceEncorenceEnterential gransimenting,reading and guidingCodeeXecution.1)單inecommentsareusedforquickexplanations.2)多l(xiāng)inecommentsexplaincomplexlogicorprovideDocumentation.3)

如何在JS中與日期和時間合作? 如何在JS中與日期和時間合作? Jul 01, 2025 am 01:27 AM

JavaScript中的日期和時間處理需注意以下幾點:1.創(chuàng)建Date對象有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設(shè)置時間信息可用get和set方法,注意月份從0開始;3.手動格式化日期需拼接字符串,也可使用第三方庫;4.處理時區(qū)問題建議使用支持時區(qū)的庫,如Luxon。掌握這些要點能有效避免常見錯誤。

為什么要將標(biāo)簽放在的底部? 為什么要將標(biāo)簽放在的底部? Jul 02, 2025 am 01:22 AM

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

JavaScript與Java:開發(fā)人員的全面比較 JavaScript與Java:開發(fā)人員的全面比較 Jun 20, 2025 am 12:21 AM

JavaScriptIspreferredforredforwebdevelverment,而Javaisbetterforlarge-ScalebackendsystystemsandSandAndRoidApps.1)JavascriptexcelcelsincreatingInteractiveWebexperienceswebexperienceswithitswithitsdynamicnnamicnnamicnnamicnnamicnemicnemicnemicnemicnemicnemicnemicnemicnddommanipulation.2)

什么是在DOM中冒泡和捕獲的事件? 什么是在DOM中冒泡和捕獲的事件? Jul 02, 2025 am 01:19 AM

事件捕獲和冒泡是DOM中事件傳播的兩個階段,捕獲是從頂層向下到目標(biāo)元素,冒泡是從目標(biāo)元素向上傳播到頂層。1.事件捕獲通過addEventListener的useCapture參數(shù)設(shè)為true實現(xiàn);2.事件冒泡是默認行為,useCapture設(shè)為false或省略;3.可使用event.stopPropagation()阻止事件傳播;4.冒泡支持事件委托,提高動態(tài)內(nèi)容處理效率;5.捕獲可用于提前攔截事件,如日志記錄或錯誤處理。了解這兩個階段有助于精確控制JavaScript響應(yīng)用戶操作的時機和方式。

JavaScript:探索用于高效編碼的數(shù)據(jù)類型 JavaScript:探索用于高效編碼的數(shù)據(jù)類型 Jun 20, 2025 am 12:46 AM

javascripthassevenfundaMentalDatatypes:數(shù)字,弦,布爾值,未定義,null,object和symbol.1)numberSeadUble-eaduble-ecisionFormat,forwidevaluerangesbutbecautious.2)

如何減少JavaScript應(yīng)用程序的有效載荷大小? 如何減少JavaScript應(yīng)用程序的有效載荷大??? Jun 26, 2025 am 12:54 AM

如果JavaScript應(yīng)用加載慢、性能差,問題往往出在payload太大,解決方法包括:1.使用代碼拆分(CodeSplitting),通過React.lazy()或構(gòu)建工具將大bundle拆分為多個小文件,按需加載以減少首次下載量;2.移除未使用的代碼(TreeShaking),利用ES6模塊機制清除“死代碼”,確保引入的庫支持該特性;3.壓縮和合并資源文件,啟用Gzip/Brotli和Terser壓縮JS,合理合并文件并優(yōu)化靜態(tài)資源;4.替換重型依賴,選用輕量級庫如day.js、fetch

See all articles