搜索
首页web前端js教程如何使用MOBX管理JavaScript应用程序状态

How to Manage Your JavaScript Application State with MobX

How to Manage Your JavaScript Application State with MobX

本文由Michel Weststrate和Aaron Boyer同行评审。感谢所有SitePoint的同行评审员,使SitePoint的内容尽善尽美!

如果您曾经使用jQuery编写过比非常简单的应用程序更复杂的应用程序,您可能遇到过保持UI不同部分同步的问题。通常,数据的更改需要反映在多个位置,并且随着应用程序的增长,您可能会发现自己陷入困境。为了控制这种混乱,通常使用事件来让应用程序的不同部分知道何时发生了更改。

那么,您今天是如何管理应用程序状态的呢?我要冒昧地说,您过度订阅了更改。没错。我什至不认识你,但我就要指出来。如果您没有过度订阅,那么我敢肯定您工作太努力了。

当然,除非您使用MobX……

关键要点

  • 利用MobX简化状态管理:利用MobX通过可观察对象有效地管理应用程序状态,减少在Redux等其他状态管理库中发现的复杂性和样板代码。
  • MobX自动更新:实现MobX的autorun功能,以自动响应状态更改更新UI组件,无需手动事件处理,从而简化整个应用程序的同步过程。
  • 使用计算值增强性能:使用MobX的计算值从状态派生数据,确保仅在必要时重新渲染组件,从而提高整体应用程序性能。
  • MobX易于上手:通过将标准对象转换为可观察对象,将MobX无缝集成到现有的JavaScript应用程序中,允许逐步采用,而无需完全重写。
  • 利用MobX操作进行事务性修改:应用MobX操作将状态修改封装在事务中,从而批量更新并最大限度地减少冗余渲染,从而获得更高效、更不易出错的代码。

什么是“状态”?

这是一个人物。嘿,那就是我!我有一个firstName、lastName和age。此外,如果我遇到麻烦,fullName()函数可能会出现。

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

您将如何通知您的各种输出(视图、服务器、调试日志)对该人员的修改?您将在何时触发这些通知?在MobX之前,我将使用触发自定义jQuery事件或js-signals的setter。这些选项为我提供了良好的服务,但是,我对它们的用法远非细致入微。如果person对象的任何部分发生更改,我将触发一个“changed”事件。

假设我有一段视图代码显示我的名字。如果我更改了我的年龄,该视图将更新,因为它与该person的changed事件绑定。

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

我们如何收紧这种过度触发?简单。只需为每个字段设置一个setter,并为每个更改设置单独的事件。等等——如果您想一次更改age和firstName,您可能会开始过度触发。您必须创建一种方法来延迟事件触发,直到两个更改都完成。这听起来像工作,而我很懒……

MobX来救援

MobX是由Michel Weststrate开发的一个简单、专注、高效且不显眼的状态管理库。

来自MobX文档:

只需对状态执行某些操作,MobX将确保您的应用程序尊重这些更改。

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});

注意到区别了吗?mobx.observable是我所做的唯一更改。让我们再次查看该console.log示例:

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

使用autorun,MobX将只观察已访问的内容。

如果您认为这很整洁,请查看以下内容:

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

person.age = 38; // 打印为空
person.lastName = 'RUBY!'; // 仍然为空
person.firstName = 'Matthew!'; // 此处触发

感兴趣吗?我知道你感兴趣。

MobX核心概念

observable

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

person.age = 38; // 打印为空
person.lastName = 'RUBY!'; // 触发
person.firstName = 'Matthew!'; // 也触发

MobX可观察对象只是对象。在这个例子中,我没有观察任何东西。此示例显示了如何开始将MobX集成到您现有的代码库中。只需使用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);

当您的可观察值发生变化时,您想做些什么,对吧?让我介绍autorun(),它将在任何引用的可观察值发生变化时触发回调。请注意,在上面的示例中,当age更改时,autorun()不会触发。

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函数了吗?注意它没有参数以及get?MobX将自动为您创建一个计算值。这是我最喜欢的MobX功能之一。注意person.fullName有什么奇怪的地方吗?再看一遍。这是一个函数,您无需调用它就可以看到结果!通常,您将调用person.fullName()而不是person.fullName。您刚刚遇到了您的第一个JS getter。

乐趣并没有到此结束!MobX将监视计算值的依赖项以进行更改,并且在它们发生更改时运行。如果没有任何更改,则将返回缓存的值。请参见下面的情况:

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);

在这里您可以看到,我已经多次命中了person.fullName计算,但是函数运行的唯一时间是当firstName或lastName发生更改时。这是MobX可以极大地加快应用程序速度的方法之一。

更多!

我不会再继续重写MobX精彩的文档了。查看文档以了解有关使用和创建可观察对象的更多方法。

(以下内容略去部分代码示例和详细解释,保留核心内容和结构)

将MobX投入使用

在过分枯燥之前,让我们构建一些东西。

这是一个简单的非MobX示例,它将显示每当人员更改时人员的全名。

注意,即使我们从未更改名字,名称也渲染了10次。您可以使用许多事件或检查某种更改的有效负载来优化此问题。这工作量太大了。

这是一个使用MobX构建的相同示例:

注意,没有事件、触发器或on。使用MobX,您正在处理最新值以及它已更改的事实。注意它只渲染了一次吗?这是因为我没有更改autorun正在监视的任何内容。

让我们构建一些稍微不那么琐碎的东西:

在这里,我们能够编辑整个person对象并自动监视数据输出。现在,此示例中有一些软点,最值得注意的是输入值与person对象不同步。让我们解决这个问题:

我知道,你还有一个抱怨:“Ruby,你渲染过度了!”你是对的。这就是为什么许多人选择使用React的原因。React允许您轻松地将输出分解成可以单独渲染的小组件。

为了完整起见,这里有一个我已优化的jQuery示例。

我会在真实的应用程序中做这样的事情吗?可能不会。如果我需要这种粒度,我随时都会使用React。当我在真实的应用程序中使用MobX和jQuery时,我使用足够细致的autorun(),以至于我没有在每次更改时都重建整个DOM。

您已经走到了这一步,所以这里是用React和MobX构建的相同示例

让我们构建一个幻灯片放映

您将如何表示幻灯片放映的状态?让我们从单个幻灯片工厂开始:

我们应该有一些东西可以聚合我们所有的幻灯片。让我们现在构建它:

幻灯片放映开始了!这更有趣,因为我们有一个可观察的幻灯片数组,它允许我们从集合中添加和删除幻灯片,并相应地更新我们的UI。接下来,我们添加activeSlide计算值,该值将根据需要保持自身最新。

让我们渲染我们的幻灯片放映。我们还没有准备好HTML输出,所以我们只会打印到控制台。

很酷,我们有一些幻灯片,autorun刚刚打印出了它们当前的状态。让我们更改一个或两个幻灯片:

看起来我们的autorun正在工作。如果您更改autorun正在监视的任何内容,它将触发。让我们将输出派生从控制台更改为HTML:

我们现在已经有了这个幻灯片放映的基本显示,但是,还没有交互性。您不能点击缩略图并更改主图像。但是,您可以轻松地使用控制台更改图像文本并添加幻灯片:

让我们创建我们的第一个也是唯一一个操作来设置选定的幻灯片。我们将不得不通过添加以下操作来修改slideShowModelFactory

您可能会问,为什么要使用操作?好问题!MobX操作不是必需的,正如我在更改可观察值的其他示例中所展示的那样。

操作在几个方面对您有所帮助。首先,所有MobX操作都在事务中运行。这意味着我们的autorun和其他MobX反应将等待操作完成后再触发。考虑一下。如果我尝试在事务之外停用活动幻灯片并激活下一个幻灯片会发生什么?我们的autorun将触发两次。第一次运行会很尴尬,因为将没有活动幻灯片可供显示。

除了它们的事务性质之外,MobX操作往往使调试更简单。我传递给mobx.action的第一个可选参数是字符串“set active slide”。此字符串可以使用MobX的调试API输出。

所以我们有我们的操作,让我们使用jQuery连接它的用法:

就是这样。您现在可以点击缩略图,并且活动状态将按预期传播。这是幻灯片放映的工作示例:

这是一个使用React的相同幻灯片放映的示例。

注意,我根本没有更改模型?就MobX而言,React只是您数据的另一种派生,例如jQuery或控制台。

jQuery幻灯片放映示例的警告

请注意,我没有以任何方式优化jQuery示例。我们在每次更改时都会破坏整个幻灯片放映DOM。通过破坏,我的意思是我们在每次点击时都会替换幻灯片放映的所有HTML。如果您要构建一个强大的基于jQuery的幻灯片放映,您可能会在初始渲染后调整DOM,方法是设置和删除活动类并更改mainImagesrc属性。

想了解更多?

如果您想了解更多关于MobX的信息,请查看下面一些其他有用的资源:

如果您有任何疑问,请在下面的评论中告诉我,或者在MobX gitter频道中找到我。

关于使用MobX管理JavaScript应用程序状态的常见问题解答(FAQ)

(以下内容略去FAQ部分,因为篇幅过长,且与核心内容关系不大。)

以上是如何使用MOBX管理JavaScript应用程序状态的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
在JavaScript中替换字符串字符在JavaScript中替换字符串字符Mar 11, 2025 am 12:07 AM

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

构建您自己的Ajax Web应用程序构建您自己的Ajax Web应用程序Mar 09, 2025 am 12:11 AM

因此,在这里,您准备好了解所有称为Ajax的东西。但是,到底是什么? AJAX一词是指用于创建动态,交互式Web内容的一系列宽松的技术。 Ajax一词,最初由Jesse J创造

如何创建和发布自己的JavaScript库?如何创建和发布自己的JavaScript库?Mar 18, 2025 pm 03:12 PM

文章讨论了创建,发布和维护JavaScript库,专注于计划,开发,测试,文档和促销策略。

如何在浏览器中优化JavaScript代码以进行性能?如何在浏览器中优化JavaScript代码以进行性能?Mar 18, 2025 pm 03:14 PM

本文讨论了在浏览器中优化JavaScript性能的策略,重点是减少执行时间并最大程度地减少对页面负载速度的影响。

如何使用浏览器开发人员工具有效调试JavaScript代码?如何使用浏览器开发人员工具有效调试JavaScript代码?Mar 18, 2025 pm 03:16 PM

本文讨论了使用浏览器开发人员工具的有效JavaScript调试,专注于设置断点,使用控制台和分析性能。

jQuery矩阵效果jQuery矩阵效果Mar 10, 2025 am 12:52 AM

将矩阵电影特效带入你的网页!这是一个基于著名电影《黑客帝国》的酷炫jQuery插件。该插件模拟了电影中经典的绿色字符特效,只需选择一张图片,插件就会将其转换为充满数字字符的矩阵风格画面。快来试试吧,非常有趣! 工作原理 插件将图片加载到画布上,读取像素和颜色值: data = ctx.getImageData(x, y, settings.grainSize, settings.grainSize).data 插件巧妙地读取图片的矩形区域,并利用jQuery计算每个区域的平均颜色。然后,使用

如何构建简单的jQuery滑块如何构建简单的jQuery滑块Mar 11, 2025 am 12:19 AM

本文将引导您使用jQuery库创建一个简单的图片轮播。我们将使用bxSlider库,它基于jQuery构建,并提供许多配置选项来设置轮播。 如今,图片轮播已成为网站必备功能——一图胜千言! 决定使用图片轮播后,下一个问题是如何创建它。首先,您需要收集高质量、高分辨率的图片。 接下来,您需要使用HTML和一些JavaScript代码来创建图片轮播。网络上有很多库可以帮助您以不同的方式创建轮播。我们将使用开源的bxSlider库。 bxSlider库支持响应式设计,因此使用此库构建的轮播可以适应任何

如何使用Angular上传和下载CSV文件如何使用Angular上传和下载CSV文件Mar 10, 2025 am 01:01 AM

数据集对于构建API模型和各种业务流程至关重要。这就是为什么导入和导出CSV是经常需要的功能。在本教程中,您将学习如何在Angular中下载和导入CSV文件

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境