首页 >web前端 >js教程 >Redux vs mobx:哪个最适合您的项目?

Redux vs mobx:哪个最适合您的项目?

William Shakespeare
William Shakespeare原创
2025-02-16 09:40:10830浏览

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