首頁 > web前端 > js教程 > Redux vs mobx:哪個最適合您的項目?

Redux vs mobx:哪個最適合您的項目?

William Shakespeare
發布: 2025-02-16 09:40:10
原創
827 人瀏覽過

Redux vs mobx:哪個最適合您的項目?

鑰匙要點

    Redux和MOBX都是開源庫,可提供客戶端的狀態管理,支持時間旅行調試,並對React/React本地框架有廣泛的支持。但是,它們的核心哲學和方法有所不同。
  • > MOBX易於學習和使用,需要更少的代碼來編寫,完全支持面向對象的編程,並使處理嵌套的數據變得容易。但是,它提供了太多的自由,這可能會導致無法實現的代碼,因此很難進行調試,並且將來可能會有更好的選擇。 由於其嚴格的國家代碼編寫準則,Redux更受歡迎,非常適合構建大型和復雜的項目,因此易於編寫測試和開發可維護的代碼。但是,它需要更多的樣板代碼,並且不適合小型項目。
  • > Redux和MOBX之間的代碼比較表明MOBX的代碼庫更精細,可以更快地構建應用程序。但是,用mobx編寫糟糕的,無與倫比的代碼非常容易。
  • >關於使用Redux還是MOBX的決定取決於您正在從事的項目類型以及可用於您的資源。
  • 對於許多JavaScript開發人員而言,Redux的最大投訴是實現功能所需的樣板代碼量。一個更好的選擇是MOBX,它提供了類似的功能,但編寫較少的代碼。
  • >
  • 對於MOBX Newbies,請快速了解MOBX創作者撰寫的這一介紹。您也可以通過本教程來獲得一些實用的經驗。
  • >
  • >本文的目的是幫助JavaScript開發人員確定這兩種州管理解決方案中哪種最適合其項目。我將這個Crud Redux項目遷移到MOBX,以本文為例。我將首先討論使用MOBX的優缺點,然後我將演示來自兩個版本的實際代碼樣本以顯示差異。
可以在GitHub上找到本文中提到的項目的代碼:>

redux crud示例

mobx crud示例

如果您喜歡這篇文章,您可能還希望註冊SitePoint Premium,並觀看我們使用React和Redux的表格工作的課程。

>
  • Redux和MOBX有什麼共同點?
  • 首先,讓我們看看它們的共同點。他們:

是開源庫

Redux vs mobx:哪個最適合您的項目?提供客戶端狀態管理

通過Redux-devtools-extension

支持時間旅行調試

不綁在特定框架

>
    對React/React本地框架有廣泛的支持。
  • 4種使用MOBX
  • 的理由
  • 現在讓我們看一下redux和mobx之間的主要區別。
  • >

    1。易於學習和使用

    對於初學者,您可以在短短30分鐘內學習如何使用MOBX。一旦學習了基礎知識,就是這樣。您無需學習新的東西。使用Redux,基本知識也很容易。但是,一旦您開始構建更複雜的應用程序,就必須處理:

    用redux-thunk
      處理異步操作
    • 用Redux-Saga
    • 簡化代碼
    • 定義選擇器要處理計算值等。
    • >
    > MOBX,所有這些情況都“神奇地”照顧了。您不需要其他圖書館來處理此類情況。

    >

    2。更少的代碼寫

    要在Redux中實現功能,您需要至少更新四個工件。這包括為還原,操作,容器和組件編寫代碼。如果您從事一個小型項目,這尤其令人討厭。 MOBX僅要求您至少更新兩個工件(即商店和視圖組件)。

    3。全面支持面向對象的編程

    >如果您更喜歡編寫面向對象的代碼,您會很高興知道可以使用OOP使用MOBX實現狀態管理邏輯。通過使用 @observable和 @observer等裝飾器,您可以輕鬆地使您的普通JavaScript組件和存儲量變化。如果您更喜歡功能編程,那就沒問題 - 也得到了支持。另一方面,Redux非常適合功能編程原則。但是,如果您需要基於類的方法,則可以使用Redux-connect-Decorator庫。

    4。處理嵌套數據很容易

    > 在大多數JavaScript應用程序中,您會發現自己使用關係或嵌套數據。要能夠在Redux商店中使用它,您必須先將其標準化。接下來,您必須編寫更多代碼來管理歸一化數據中參考的跟踪。 >

    在MOBX中,建議以非正式的形式存儲您的數據。 MOBX可以跟踪您的關係,並會自動重新渲染更改。通過使用域對象存儲數據,您可以直接引用其他商店中定義的其他域對象。此外,您可以使用(@)計算的裝飾器和修飾符來可觀察到可輕鬆解決複雜的數據挑戰。

    3個不使用MOBX

    的理由

    1。太多的自由

    Redux是一個框架,可提供有關您如何編寫狀態代碼的嚴格指南。這意味著您可以輕鬆編寫測試並開發可維護的代碼。 MOBX是一個庫,沒有關於如何實施它的規則。這樣做的危險是,捷徑很容易進行快速修復,這可能導致無法實現的代碼。

    2。很難調試

    MOBX的內部代碼“神奇地”處理大量邏輯,以使您的應用程序具有反應性。在商店和組件之間,您的數據通過一個無形的區域,這使得在遇到問題時很難進行調試。如果您直接在組件中更改狀態,而無需使用@Actions,則很難確定錯誤的來源。

    >

    3。可能有更好的替代品與mobx

    在軟件開發中,

    始終出現新的新興趨勢。在短短幾年內,當前的軟件技術可以快速失去動力。目前,有幾種解決方案與Redux和MOBX競爭。一些示例是中繼/apollo&GraphQl,alt.js和連身褲。這些技術中的任何一種都有可能成為最受歡迎的技術。如果您真的想知道哪一個最適合您,則必須嘗試所有這些。

    代碼比較:redux vs mobx

    足夠的理論,讓我們看一下代碼。首先,我們比較每個版本如何進行引導。

    >

    >引導

    redux版本: 在Redux中,我們首先定義我們的商店,然後通過提供商將其傳遞給應用程序。我們還需要定義Redux-Thunk和Redux-Promise-Middleware來處理異步功能。 redux-devtools-擴展使我們可以在及時旅行模式下調試我們的商店。

    mobx版本: 在MOBX中,我們需要設置多個商店。在這種情況下,我只使用一家商店,我將其放在一個名為AllStores的集合中。然後使用提供商將商店集合傳遞到應用程序。 如前所述,MOBX不需要外部庫來處理異步操作,因此行較少。但是,我們確實需要MOBX-REMOTEDEV才能連接到Redux-Devtools-擴展調試工具。
    <span>// src/store.js
    </span><span>import <span>{ applyMiddleware, createStore }</span> from "redux";
    </span><span>import thunk from "redux-thunk";
    </span><span>import promise from "redux-promise-middleware";
    </span><span>import <span>{ composeWithDevTools }</span> from 'redux-devtools-extension';
    </span><span>import rootReducer from "./reducers";
    </span>
    <span>const middleware = composeWithDevTools(applyMiddleware(promise(), thunk));
    </span>
    <span>export default createStore(rootReducer, middleware);
    </span>
    <span>-------------------------------------------------------------------------------
    </span>
    <span>// src/index.js
    </span>…
    <span>ReactDOM.render(
    </span>  <span><span><span><BrowserRouter</span>></span>
    </span><span>    <span><span><Provider</span> store<span>={store}</span>></span>
    </span><span>      <span><span><App</span> /></span>
    </span><span>    <span><span></Provider</span>></span>
    </span><span>  <span><span></BrowserRouter</span>></span>,
    </span>  <span>document.getElementById('root')
    </span><span>);
    </span>
    登入後複製
    登入後複製

    在兩個版本中,這裡的代碼量大致相同。 MOBX的導入語句較少。

    props注入

    <span>// src/stores/index.js
    </span><span>import remotedev from 'mobx-remotedev';
    </span><span>import <span>Store</span> from './store';
    </span>
    <span>const contactConfig = {
    </span>  <span>name:'Contact Store',
    </span>  <span>global: true,
    </span>  <span>onlyActions:true,
    </span>  <span>filters: {
    </span>    <span>whitelist: <span>/fetch<span>|update|create|Event|entity|entities|handleErrors</span>/</span>
    </span>  <span>}
    </span><span>};
    </span>
    <span>const contactStore = new Store('api/contacts');
    </span>
    <span>const allStores = {
    </span>  <span>contactStore: remotedev(contactStore, contactConfig)
    </span><span>};
    </span>
    <span>export default allStores;
    </span>
    <span>-------------------------------------------------------------------------------
    </span>
    <span>// src/index.js
    </span>…
    <span>ReactDOM.render(
    </span>  <span><span><span><BrowserRouter</span>></span>
    </span><span>    <span><span><Provider</span> stores<span>={allStores}</span>></span>
    </span><span>      <span><span><App</span> /></span>
    </span><span>    <span><span></Provider</span>></span>
    </span><span>  <span><span></BrowserRouter</span>></span>,
    </span>  <span>document.getElementById('root')
    </span><span>);
    </span>
    登入後複製
    登入後複製
    redux版本: 在Redux中,使用React-Redux的Connect()函數將狀態和動作傳遞給道具。

    >

    mobx版本: 在MOBX中,我們只是注入商店集合。我們在容器或組件類的頂部使用@Inject來執行此操作。這使道具中的商店可用,這又使我們能夠訪問特定的商店並將其傳遞給兒童組件。狀態和操作都是通過商店對像中的屬性訪問的,因此無需像redux中的情況那樣單獨傳遞它們。

    MOBX版本似乎更容易閱讀。但是,我們可以使用Redux-Connect-Decorator來簡化Redux代碼。在這種情況下,不會有明確的贏家。
    <span>// src/pages/contact-form-page.js
    </span>…
      <span>// accessing props
    </span>  <span><span><span><ContactForm</span>
    </span></span><span>    <span>contact<span>={this.props.contact}</span>
    </span></span><span>    <span>loading<span>={this.props.loading}</span>
    </span></span><span>    <span>onSubmit<span>={this.submit}</span>
    </span></span><span>  <span>/></span>
    </span>…
    
    <span>// function for injecting state into props
    </span><span>function mapStateToProps(state) {
    </span>  <span>return {
    </span>    <span>contact: state.contactStore.contact,
    </span>    <span>errors: state.contactStore.errors
    </span>  <span>}
    </span><span>}
    </span>
    <span>// injecting both state and actions into props
    </span><span>export default connect(mapStateToProps, { newContact,
    </span>  saveContact<span>,
    </span>  fetchContact<span>,
    </span>  updateContact
    <span>})(ContactFormPage);
    </span>
    登入後複製

    定義商店,動作和還原器

    <span>// src/pages/contact-form-page.js
    </span>
    …
    @<span>inject("stores") @observer // injecting store into props
    </span><span>class ContactFormPage extends Component {
    </span>…
      <span>// accessing store via props
    </span>  <span>const { contactStore:store } = this.props.stores;
    </span>  <span>return (
    </span>      <span><span><span><ContactForm</span>
    </span></span><span>        <span>store<span>={store}</span>
    </span></span><span>        <span>form<span>={this.form}</span>
    </span></span><span>        <span>contact<span>={store.entity}</span>
    </span></span><span>      <span>/></span>
    </span>  <span>)
    </span>…
    <span>}
    </span>
    登入後複製
    要保持這篇文章的精益,我將向您展示一個只有一個動作的代碼樣本。

    redux版本: 在redux中,我們需要定義動作和還原器。

    <span>// src/store.js
    </span><span>import <span>{ applyMiddleware, createStore }</span> from "redux";
    </span><span>import thunk from "redux-thunk";
    </span><span>import promise from "redux-promise-middleware";
    </span><span>import <span>{ composeWithDevTools }</span> from 'redux-devtools-extension';
    </span><span>import rootReducer from "./reducers";
    </span>
    <span>const middleware = composeWithDevTools(applyMiddleware(promise(), thunk));
    </span>
    <span>export default createStore(rootReducer, middleware);
    </span>
    <span>-------------------------------------------------------------------------------
    </span>
    <span>// src/index.js
    </span>…
    <span>ReactDOM.render(
    </span>  <span><span><span><BrowserRouter</span>></span>
    </span><span>    <span><span><Provider</span> store<span>={store}</span>></span>
    </span><span>      <span><span><App</span> /></span>
    </span><span>    <span><span></Provider</span>></span>
    </span><span>  <span><span></BrowserRouter</span>></span>,
    </span>  <span>document.getElementById('root')
    </span><span>);
    </span>
    登入後複製
    登入後複製

    mobx版本: 在MOBX中,動作和還原器的邏輯是在一個類中完成的。我定義了一個異步操作,該操作稱收到響應後獲取的另一個動作實體。

    >

    >由於MOBX使用OOP樣式,因此對此處定義的商店類進行了重構,以便於使用類構造函數輕鬆創建多個商店。因此,這裡演示的代碼是基本代碼,該代碼與特定域名商店沒有綁定。 >

    <span>// src/stores/index.js
    </span><span>import remotedev from 'mobx-remotedev';
    </span><span>import <span>Store</span> from './store';
    </span>
    <span>const contactConfig = {
    </span>  <span>name:'Contact Store',
    </span>  <span>global: true,
    </span>  <span>onlyActions:true,
    </span>  <span>filters: {
    </span>    <span>whitelist: <span>/fetch<span>|update|create|Event|entity|entities|handleErrors</span>/</span>
    </span>  <span>}
    </span><span>};
    </span>
    <span>const contactStore = new Store('api/contacts');
    </span>
    <span>const allStores = {
    </span>  <span>contactStore: remotedev(contactStore, contactConfig)
    </span><span>};
    </span>
    <span>export default allStores;
    </span>
    <span>-------------------------------------------------------------------------------
    </span>
    <span>// src/index.js
    </span>…
    <span>ReactDOM.render(
    </span>  <span><span><span><BrowserRouter</span>></span>
    </span><span>    <span><span><Provider</span> stores<span>={allStores}</span>></span>
    </span><span>      <span><span><App</span> /></span>
    </span><span>    <span><span></Provider</span>></span>
    </span><span>  <span><span></BrowserRouter</span>></span>,
    </span>  <span>document.getElementById('root')
    </span><span>);
    </span>
    登入後複製
    登入後複製
    信不信由你,兩個版本中定義的邏輯執行相同的任務,這是:>

    更新UI加載狀態
    • >提取數據異步
    • 捕獲異常並更新狀態。
    • 在Redux中,我們使用了33行代碼。在MOBX中,我們使用了大約14行代碼來達到相同的結果! MOBX版本的一個主要好處是,您幾乎可以在幾乎所有的域存儲類中重複使用基本代碼,而幾乎沒有修改。這意味著您可以更快地構建應用程序。
    其他差異

    要在Redux中創建表單,我使用了Redux-Form。在MOBX中,我使用了MOBX反應形式。這兩個庫都是成熟的,可以幫助您輕鬆處理邏輯。就個人而言,我更喜歡MOBX反應形式,因為它允許您通過插件驗證字段。使用Redux-form,您要么編寫自己的驗證代碼,要么可以導入驗證軟件包來處理您的驗證。

    MOBX的一個微小的缺點是,您無法在可觀察的對像中直接訪問某些功能,因為它們不是真正的JavaScript對象。幸運的是,他們提供了函數tojs(),您可以用來將可觀察的對象轉換為普通的JavaScript對象。

    結論

    >很明顯,您可以看到MOBX的代碼庫要瘦得多。使用OOP樣式和良好的開發實踐,您可以快速構建應用程序。主要缺點是編寫糟糕的,無與倫比的代碼非常容易。

    > 另一方面,Redux更受歡迎,非常適合構建大型和復雜的項目。這是一個嚴格的框架,並確保每個開發人員都撰寫易於測試和維護的代碼。但是,它不太適合小型項目。 儘管MOBX的缺點,但如果您遵循良好的做法,您仍然可以構建大型項目。用阿爾伯特·愛因斯坦(Albert Einstein)的話說:“盡可能簡單,但不是更簡單”。

    >我希望我提供了足夠的信息,以說明是遷移到MOBX還是堅持使用Redux的情況。最終,決定取決於您正在從事的項目類型以及可用的資源。 加載玩家…

    Redux vs mobx

    的常見問題(常見問題解答)

    Redux和MobX之間的主要區別是什麼? Redux遵循基於通量架構的嚴格且可預測的狀態管理模式。它有一個商店,國家的變化是通過動作和減少器進行的。另一方面,MOBX採用了一種更靈活,更直觀的方法。它允許多家商店,狀態更改直接通過動作進行。

    對於大規模應用程序而言,REDUX或MOBX更好?

    > Redux通常由於其可預測的和可預測的應用程序而受到大規模應用程序的青睞。透明狀態管理。嚴格的動作模式和還原器使跟踪狀態變化變得更加容易,這對於復雜的應用程序至關重要。但是,MOBX具有更靈活的方法,也可以在大規模應用中有效地使用,尤其是當開發人員更喜歡較少的樣板和更簡單的編碼樣式時。

    >

    >如何在Redux和Mobx之間進行比較。與MOBX相比,?

    的學習曲線更陡峭。它需要理解動作,還原器和商店的概念,以及它們如何相互作用。另一方面,通常認為MOBX使用更熟悉的編程概念(例如可觀察和動作),並且需要更少的樣板代碼。

    與MOBX相比,Redux如何處理異步動作? Redux需要諸如Redux-Thunk或Redux-Saga之類的中間件來處理異步動作。這些中間件允許操作派遣其他操作,或延遲派遣操作。另一方面,MOBX可以直接處理異步動作而無需其他中間件。

    >可以在單個應用程序中一起使用redux和mobx嗎?一起在一個應用程序中使用。但是,這通常不是這樣做,因為它可能導致不必要的複雜性。通常,建議根據項目的特定需求和約束選擇一個或另一個。

    >在redux和mobx之間的測試如何?測試。它可預測的狀態變化和純粹的功能(還原器)使其易於測試。 MOBX雖然由於其更具動態的性質而無法進行測試,但仍然可以使用Jest。

    > redux和mobx之間的性能如何?

    > redux和mobx都具有良好的性能特徵,並且可以有效地處理大型狀態樹。但是,由於其細粒度的可觀察性系統,MOBX在某些情況下可以具有優勢,該系統僅更新直接受狀態變化影響的組件。

    >社區支持和生態系統如何比較Redux和Mobx之間?有更多用於學習Redux的資源,還有更​​多旨在與之合作的第三方庫。但是,MOBX一直在越來越受歡迎。更喜歡更直接,更少的樣板編碼樣式,或者當項目需要對狀態更新進行細粒度控制時。當團隊對面向對象的編程概念更舒適時,這也是一個不錯的選擇,因為MOBX強烈利用了這些概念。

    >

    >在某些用例中,Redux可能比MOBX更好? > REDUX可能是對狀態變化的可預測性和透明度至關重要的大規模應用的更好選擇。當團隊對功能編程概念感到滿意時,這也是一個不錯的選擇,因為Redux強烈利用了這些概念。此外,Redux的成熟生態系統和大型社區可能是決定因素。

以上是Redux vs mobx:哪個最適合您的項目?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板