Heim  >  Artikel  >  Web-Frontend  >  Ausführliche Erläuterung der Auswahlbeispiele von Redux und Mobx

Ausführliche Erläuterung der Auswahlbeispiele von Redux und Mobx

小云云
小云云Original
2018-02-09 13:17:281446Durchsuche

Redux und Mobx sind derzeit beide beliebte Datenflussmodelle. Es scheint, dass die Community natürlich verwirrt ist, was sie als Ersatz für Redux wählen soll. Der Entwickler ist sich nicht sicher, welche Lösung er wählen soll. Dieses Problem ist nicht auf Redux und Mobx beschränkt. Immer wenn die Wahl besteht, fragen sich die Menschen, wie sie ein Problem am besten lösen können. Was ich jetzt schreibe, besteht darin, die Verwirrung zwischen den beiden Zustandsverwaltungsbibliotheken Redux und Mobx zu beseitigen.

Die meisten Artikel verwenden React, um die Verwendung von Mobx und Redux vorzustellen. In den meisten Fällen können Sie React jedoch durch Angular, Vue oder etwas anderes ersetzen.

Anfang 2016 habe ich eine ziemlich große Anwendung mit React + Redux geschrieben. Als ich entdeckte, dass Mobx als Alternative zu Redux verwendet werden kann, nahm ich mir die Zeit, die Anwendung von Redux auf Mobx umzugestalten. Jetzt kann ich sie sehr komfortabel nutzen und ihre Verwendung erklären.

Worüber wird in diesem Artikel gesprochen? Wenn Sie nicht vorhaben, einen so langen Artikel zu lesen (TLDR: zu lang, nicht gelesen (bitte bringen Sie Ihre eigene Leiter mit, um diesen Link anzuzeigen)), können Sie sich das Inhaltsverzeichnis ansehen. Ich möchte aber noch näher darauf eingehen: Zunächst möchte ich kurz darauf eingehen, welche Probleme die Landesverwaltungsbibliothek für uns löst. Schließlich können wir es genauso gut machen, wenn wir beim Schreiben von React nur setState() verwenden oder beim Schreiben anderer SPA-Frameworks setState() und ähnliche Methoden verwenden. Zweitens werde ich kurz auf die Gemeinsamkeiten und Unterschiede zwischen ihnen eingehen. Drittens werde ich Anfängern im React-Ökosystem zeigen, wie sie die Zustandsverwaltung von React erlernen können. Freundliche Erinnerung: Bevor Sie in Mobx und Redux eintauchen, verwenden Sie bitte zuerst setState(). Wenn Sie bereits über eine Anwendung verfügen, die Mobx oder Redux verwendet, erkläre ich Ihnen abschließend, wie ich die Umgestaltung von einer dieser Zustandsverwaltungsbibliotheken in die andere erläutere.

Inhaltsverzeichnis

Welches Problem versuchen wir zu lösen?

Was ist der Unterschied zwischen Mobx und Redux?

Lernkurve des React State Management

Eine andere State-Management-Lösung ausprobieren?

Abschließende Gedanken

Welches Problem versuchen wir zu lösen?

Jeder möchte die Zustandsverwaltung in seinen Anwendungen nutzen. Aber welches Problem löst es für uns? Viele Leute haben beim Starten einer kleinen Anwendung eine Statusverwaltungsbibliothek eingeführt. Alle reden über Mobx und Redux, oder? Die meisten Anwendungen erfordern jedoch zu Beginn keine umfassende Zustandsverwaltung. Dies kann sogar gefährlich sein, da diese Menschen nicht in der Lage sein werden, die Probleme zu erleben, die Bibliotheken wie Mobx und Redux lösen sollen.

Die aktuelle Situation besteht darin, Komponenten zum Erstellen einer Front-End-Anwendung zu verwenden. Komponenten haben ihren eigenen internen Zustand. In React wird der oben genannte lokale Zustand beispielsweise mit this.state und setState() gehandhabt. Aber die Zustandsverwaltung des lokalen Zustands kann in einer aufgeblähten Anwendung schnell verwirrend werden, weil:

Eine Komponente muss den Zustand mit einer anderen Komponente teilen

Eine Komponente muss den Zustand ändern einer anderen Komponente

bis zu einem gewissen Grad wird es immer schwieriger, den Zustand der Anwendung abzuleiten. Es wird zu einer verwirrenden Anwendung, da viele Zustandsobjekte den Zustand des anderen auf Komponentenebene ändern. In den meisten Fällen müssen Zustandsobjekte und Zustandsänderungen nicht an eine Komponente gebunden werden. Wenn Sie Zustände heraufstufen, sind diese über die Komponentenstruktur verfügbar.

Die Lösung besteht also darin, eine Zustandsverwaltungsbibliothek wie Mobx oder Redux einzuführen. Es bietet Tools zum Speichern des Status, zum Ändern des Status und zum Aktualisieren des Status irgendwo. Sie können den Status von einem Ort aus abrufen, ihn von einem Ort aus ändern und seine Aktualisierungen von einem Ort aus abrufen. Es folgt dem Prinzip einer einzigen Datenquelle. Dadurch können wir leichter auf Zustandswerte und Zustandsänderungen schließen, da diese von unseren Komponenten entkoppelt sind.

Zustandsverwaltungsbibliotheken wie Redux und Mobx verfügen im Allgemeinen über begleitende Tools wie React-Redux und Mobx-React, die in React verwendet werden und es Ihren Komponenten ermöglichen, den Zustand abzurufen. Typischerweise werden diese Komponenten Containerkomponenten oder genauer gesagt verbundene Komponenten genannt. Solange Sie Ihre Komponente zu einer verbundenen Komponente aktualisieren, können Sie den Status überall in der Komponentenhierarchie abrufen und ändern.

Was ist der Unterschied zwischen Mobx und Redux?

Bevor wir uns mit den Unterschieden zwischen Redux und Mobx befassen, möchte ich über die Ähnlichkeiten zwischen ihnen sprechen.

Beide Bibliotheken werden zum Verwalten des Status von JavaScript-Anwendungen verwendet. Sie müssen nicht mit React gebündelt werden, sondern können auch mit anderen Bibliotheken wie AngularJs und VueJs verwendet werden. Aber sie integrieren sich sehr gut in die Ideen von React.

Wenn Sie sich für eine der Statusverwaltungsoptionen entscheiden, werden Sie sich nicht eingesperrt fühlen. Denn Sie können jederzeit auf eine andere Lösung wechseln. Sie können von Mobx zu Redux oder von Redux zu Mobx wechseln. Im Folgenden zeige ich Ihnen, wie das geht.

Dan Abramovs Redux ist von der Flux-Architektur abgeleitet. Anders als Flux verwendet Redux einen einzelnen Store anstelle mehrerer Stores, um den Status zu speichern. Darüber hinaus verwendet es reine Funktionen anstelle von Dispatchern, um den Status zu ändern. Wenn Sie mit Flux nicht vertraut sind und noch nicht mit der Statusverwaltung vertraut sind, sollten Sie dies nicht tun Lassen Sie sich von diesem Inhalt täuschen.

Redux wird von FP-Prinzipien (Functional Programming) beeinflusst. FP kann in JavaScript verwendet werden, aber viele Leute haben einen Hintergrund in objektorientierten Sprachen wie Java. Es fällt ihnen zunächst schwer, sich an die Prinzipien der funktionalen Programmierung zu gewöhnen. Aus diesem Grund ist Mobx für Anfänger möglicherweise einfacher.

Da Redux FP umfasst, verwendet es reine Funktionen. Eine reine Funktion, die Eingaben entgegennimmt und Ausgaben zurückgibt und keine anderen Abhängigkeiten aufweist. Eine reine Funktion hat bei gleichen Eingaben immer die gleiche Ausgabe und keine Nebenwirkungen.


(state, action) => newState

Ihr Redux-Status ist unveränderlich. Sie sollten immer einen neuen Status zurückgeben, anstatt den ursprünglichen Status zu ändern. Sie sollten keine Statusänderungen oder Änderungen basierend auf Objektreferenzen durchführen.


// don't do this in Redux, because it mutates the array
function addAuthor(state, action) {
 return state.authors.push(action.author);
}
// stay immutable and always return a new object
function addAuthor(state, action) {
 return [ ...state.authors, action.author ];
}

Schließlich ist in der Redewendung von Redux das Zustandsformat wie eine Datenbank standardisiert. Entitäten verweisen aufeinander nur über ihre ID, was eine bewährte Methode ist. Obwohl dies nicht jeder tut, können Sie den Zustand auch mit normalizr normalisieren. Der normalisierte Zustand ermöglicht es Ihnen, einen flachen Zustand beizubehalten und Entitäten als eine einzige Datenquelle beizubehalten.


{
 post: {
 id: 'a',
 authorId: 'b',
 ...
 },
 author: {
 id: 'b',
 postIds: ['a', ...],
 ...
 }
}

Michel Weststrates Mobx ist von objektorientierter Programmierung und reaktiver Programmierung beeinflusst. Es verpackt den Zustand in ein beobachtbares Objekt, sodass Ihr Staat über alle Funktionen von Observable verfügt. Zustandsdaten können nur gewöhnliche Setter und Getter haben, aber beobachtbar ermöglicht es uns, aktualisierte Werte zu erhalten, wenn sich die Daten ändern.

Der Status von Mobx ist veränderbar, daher ändern Sie den Status direkt:


function addAuthor(author) {
 this.authors.push(author);
}

Ansonsten bleibt die Statusentität verschachtelte Datenstrukturen sich aufeinander beziehen. Sie müssen den Status nicht standardisieren, sondern ihn verschachtelt halten.


{
 post: {
 id: 'a',
 ...
 author: {
 id: 'b',
 ...
 }
 }
}

Einzelner Store vs. mehrere Stores

In Redux geben Sie den gesamten Status in A global ein speichern. Dieses Store-Objekt ist Ihre einzige Datenquelle. Andererseits ermöglichen Ihnen mehrere Reduzierer, den unveränderlichen Zustand zu ändern.

Mobx hingegen nutzt mehrere Stores. Ähnlich wie bei Redux-Reduzierern können Sie auf technischer Ebene oder in einer Domäne teilen und erobern. Möglicherweise möchten Sie Ihre Domänenentitäten in verschiedenen Speichern speichern und dennoch die Kontrolle über den Status in der Ansicht behalten. Schließlich konfigurieren Sie den Status so, dass Ihre Anwendung angemessen aussieht.

Technisch gesehen können Sie in Redux auch mehrere Stores nutzen. Niemand zwingt Sie, nur ein Geschäft zu nutzen. Dies ist jedoch nicht die empfohlene Verwendung von Redux. Denn das verstößt gegen Best Practices. In Redux reagiert Ihr einzelner Shop auf Aktualisierungen durch globale Ereignisse auf Reduzierern.

Wie benutzt man?

Sie müssen dem folgenden Code folgen, um die Verwendung von Redux zu erlernen. Fügen Sie zunächst ein Benutzerarray zum globalen Status hinzu. Sie können sehen, dass ich den Objektverbreitungsoperator verwende, um ein neues Objekt zurückzugeben. Sie können Object.assign() auch in ES6 (ursprünglich ES5, eigentlich ES6) verwenden, um unveränderliche Objekte zu bearbeiten.


const initialState = {
 users: [
 {
 name: 'Dan'
 },
 {
 name: 'Michel'
 }
 ]
};
// reducer
function users(state = initialState, action) {
 switch (action.type) {
 case 'USER_ADD':
 return { ...state, users: [ ...state.users, action.user ] };
 default:
 return state;
 }
}
// action
{ type: 'USER_ADD', user: user };

Sie müssen „dispatch({ type: 'USER_ADD', user: user });“ verwenden, um einen neuen Benutzer zum globalen Status hinzuzufügen.

In Mobx verwaltet ein Geschäft nur einen Unterstatus (genau wie der Reduzierer, der den Unterstatus in Redux verwaltet), aber Sie können den Status direkt ändern.

@observable ermöglicht es uns, Zustandsänderungen zu beobachten.


class UserStore {
 @observable users = [
 {
 name: 'Dan'
 },
 {
 name: 'Michel'
 }
 ];
}

Jetzt können wir die Store-Instanzmethode aufrufen: userStore.users.push(user);. Dies ist eine bewährte Methode, obwohl die Verwendung von Aktionen zum Ändern des Status expliziter ist.


class UserStore {
 @observable users = [
 {
 name: 'Dan'
 },
 {
 name: 'Michel'
 }
 ];
 @action addUser = (user) => {
 this.users.push(user);
 }
}

In Mobx können Sie useStrict() hinzufügen, um die Verwendung von Aktionen zu erzwingen. Jetzt können Sie die Methode userStore.addUser(user); auf der Store-Instanz aufrufen, um Ihren Status zu ändern.

Sie haben gesehen, wie Sie den Status in Redux und Mobx aktualisieren. Sie sind unterschiedlich. Sie können den Status nur mit expliziten Aktionen ändern, während Sie den Status direkt ohne Verwendung von Aktionen ändern können kann Strict( ) verwenden, um explizite Aktionen zu verwenden.

Lernkurve des React State Managements

React-Anwendungen nutzen Redux und Mobx in großem Umfang. Sie sind jedoch unabhängige Zustandsverwaltungsbibliotheken und können überall außer React verwendet werden. Ihre Interop-Bibliothek ermöglicht es uns, React-Komponenten einfach zu verbinden. React-Redux für Redux + React und Mobx-React für MobX + React. Ich werde später erklären, wie sie im React-Komponentenbaum verwendet werden.

In jüngsten Diskussionen wurde über die Lernkurve von Redux debattiert. Dies geschieht normalerweise in folgendem Szenario: Reagieren Sie auf Anfänger, die Redux für die Zustandsverwaltung verwenden möchten. Die meisten Leute denken, dass React und Redux allein schon eine hohe Lernkurve haben und dass die Kombination der beiden außer Kontrolle geraten kann. Eine Alternative ist Mobx, da es eher für Anfänger geeignet ist.

然而,我会建议 React 的初学者一个学习状态管理的新方法。先学习React 组件内部的状态管理功能。在 React 应用,你首先会学到生命周期方法,而且你会用 setState() 和 this.state 解决本地的状态管理。我非常推荐上面的学习路径。不然你会在 React 的生态中迷失。在这条学习路径的最后,你会认识到组件内部管理状态难度越来越大。毕竟那是 The Road to learn React 书里如何教授 React 状态管理的方法。

现在我们重点讨论 Redux 和 Mobx 为我们解决了什么问题?它俩都提供了在组件外部管理应用状态的方法。state 与组件相互解耦,组件可以读取 state ,修改 state ,有新 state 时更新。这个 state 是单一数据源。

现在你需要选择其中一个状态管理库。这肯定是要第一时间解决的问题。此外,在开发过相当大的应用之后,你应该能很自如使用 React 。

初学者用 Redux 还是 Mobx ?

一旦你对 React 组件和它内部的状态管理熟悉了,你就能选择出一个状态管理库来解决你的问题。在我两个库都用过后,我想说 Mobx 更适合初学者。我们刚才已经看到 Mobx 只要更少的代码,甚至它可以用一些我们现在还不知道的魔法注解。
用 Mobx 你不需要熟悉函数式编程。像“不可变”之类的术语对你可能依然陌生。函数式编程是不断上升的范式,但对于大部分 JavaScript 开发者来说是新奇的。虽然它有清晰的趋势,但并非所有人都有函数式编程的背景,有面向对象背景的开发者可能会更加容易适应 Mobx 的原则。

   注:Mobx 可以很好的在 React 内部组件状态管理中代替 setState,我还是建议继续使用 setState() 管理内部状态。但链接文章很清楚的说明了在 React 中用 Mobx 完成内部状态管理是很容易的。                                                                      

规模持续增长的应用

在 Mobx 中你改变注解过的对象,组件就会更新。Mobx 比 Redux 使用了更多的内部魔法实现,因此在刚开始的时候只要更少的代码。有 Angular 背景的会觉得跟双向绑定很像。你在一个地方保存 state ,通过注解观察 state ,一旦 state 修改组件会自动的更新。

Mobx 允许直接在组件树上直接修改 state 。


// component
<button onClick={() => store.users.push(user)} />

更好的方式是用 store 的 @action 。


// component
<button onClick={() => store.addUser(user)} />
// store
@action addUser = (user) => {
 this.users.push(user);
}

用 actions 修改 state 更加明确。上面也提到过,有个小功能可以强制的使用 actions 修改 state 。


// root file
import { useStrict } from &#39;mobx&#39;;
useStrict(true);

这样的话第一个例子中直接修改 store 中的 state 就不再起作用了。前面的例子展示了怎样拥抱 Mobx 的最佳实践。此外,一旦你只用 actions ,你就已经使用了 Redux 的约束。

在快速启动一个项目时,我会推荐使用 Mobx ,一旦应用开始变得越来越大,越来越多的人开发时,遵循最佳实践就很有意义,如使用明确的 actions 。这是拥抱 Redux 的约束:你永远不能直接修改 state ,只能使用 actions 。

迁移到 Redux

一旦应用开始变得越来越大,越来越多的人开发时,你应该考虑使用 Redux 。它本身强制使用明确的 actions 修改 state 。action 有 type 和 payload 参数,reducer 可以用来修改 state 。这样的话,一个团队里的开发人员可以很简单的推断 state 的修改。


// reducer
(state, action) => newState

Redux 提供状态管理的整个架构,并有清晰的约束规则。这是 Redux 的成功故事。

另一个 Redux 的优势是在服务端使用。因为我们使用的是纯 JavaScript ,它可以在网络上传输 state 。序列化和反序列化一个 state 对象是直接可用的。当然 Mobx 也是一样可以的。

Mobx 是无主张的,但你可以通过 useStrict() 像 Redux 一样使用清晰的约束规则。这就是我为什么没说你不能在扩张的应用中使用 Mobx ,但 Redux 是有明确的使用方式的。而 Mobx 甚至在文档中说:“ Mobx 不会告诉你如何组织代码,哪里该存储 state 或 怎么处理事件。”所以开发团队首先要确定 state 的管理架构。

状态管理的学习曲线并不是很陡峭。我们总结下建议:React 初学者首先学习恰当的使用 setState() 和 this.state 。一段时间之后你将会意识到在 React 应用中仅仅使用 setState() 管理状态的问题。当你寻找解决方案时,你会在状态管理库 Mobx 或 Redux 的选择上犹豫。应该选哪个呢?由于 Mobx 是无主张的,使用上可以和 setState() 类似,我建议在小项目中尝试。一旦应用开始变得越来越大,越来越多的人开发时,你应该考虑在 Mobx 上实行更多的限制条件或尝试使用 Redux 。我使用两个库都很享受。即使你最后两个都没使用,了解到状态管理的另一种方式也是有意义的。

尝试另一个状态管理方案?

你可能已经使用了其中一个状态管理方案,但是想考虑另一个?你可以比较现实中的 Mobx 和 Redux 应用。我把所有的文件修改都提交到了一个Pull Request 。在这个 PR 里,项目从 Redux 重构成了 Mobx ,反之亦然,你可以自己实现。我不认为有必要和 Redux 或 Mobx 耦合,因为大部分的改变是和其他任何东西解耦的。

你主要需要将 Redux 的 Actions、Action Creator、 Action Types、Reducer、Global Store 替换成 Mobx 的 Stores 。另外将和 React 组件连接的接口 react-redux 换成 mobx-react 。presenter + container pattern 依然可以执行。你仅仅还要重构容器组件。在 Mobx 中可以使用 inject 获得 store 依赖。然后 store 可以传递 substate 和 actions 给组件。Mobx 的 observer 确保组件在 store 中 observable 的属性变化时更新。


import { observer, inject } from &#39;mobx-react&#39;;
...
const UserProfileContainer = inject(
 &#39;userStore&#39;
)(observer(({
 id,
 userStore,
}) => {
 return (
 <UserProfile
 user={userStore.getUser(id)}
 onUpdateUser={userStore.updateUser}
 />
 );
}));

Redux 的话,你使用 mapStateToProps 和 mapDispatchToProps 传递 substate 和 actions 给组件。


import { connect } from &#39;react-redux&#39;;
import { bindActionCreators } from &#39;redux&#39;;
...
function mapStateToProps(state, props) {
 const { id } = props;
 const user = state.users[id];
 return {
 user,
 };
}
function mapDispatchToProps(dispatch) {
 return {
 onUpdateUser: bindActionCreators(actions.updateUser, dispatch),
 };
}
const UserProfileContainer = connect(mapStateToProps, mapDispatchToProps)(UserProfile);

这有一篇怎样将 Redux 重构为 Mobx指南。但就像我上面说过的,反过来一样也是可以的。一旦你选择了一个状态管理库,你会知道那并没有什么限制。它们基本上是和你的应用解耦的,所以是可以替换的。

最后思考

每当我看 Redux vs Mobx 争论下的评论时,总会有下面这条:“Redux 有太多的样板代码,你应该使用 Mobx,可以减少 xxx 行代码”。这条评论也许是对的,但没人考虑得失,Redux 比 Mobx 更多的样板代码,是因为特定的设计约束。它允许你推断应用状态即使应用规模很大。所以围绕 state 的仪式都是有原因的。

Redux 库非常小,大部分时间你都是在处理纯 JavaScript 对象和数组。它比 Mobx 更接近 vanilla JavaScript 。Mobx 通过包装对象和数组为可观察对象,从而隐藏了大部分的样板代码。它是建立在隐藏抽象之上的。感觉像是出现了魔法,但却很难理解其内在的机制。Redux 则可以简单通过纯 JavaScript 来推断。它使你的应用更简单的测试和调试。
另外,我们重新回到单页应用的最开始来考虑,一系列的单页应用框架和库面临着相同的状态管理问题,它最终被 flux 模式解决了。Redux 是这个模式的成功者。

Mobx 则又处在相反的方向。我们直接修改 state 而没有拥抱函数式编程的好处。对一些开发者来说,这让他们觉得像双向绑定。一段时间之后,由于没有引入类似 Redux 的状态管理库,他们可能又会陷入同样的问题。状态管理分散在各个组件,导致最后一团糟。

使用 Redux,你有一个既定的模式组织代码,而 Mobx 则无主张。但拥抱 Mobx 最佳实践会是明智的。 开发者需要知道如何组织状态管理从而更好的推断它。不然他们就会想要直接在组件中修改它。

两个库都非常棒。Redux 已经非常完善,Mobx 则逐渐成为一个有效的替代。

相关推荐:

react-redux中connect的装饰器用法

如何理解 redux

在React中使用Redux的实例详解

Das obige ist der detaillierte Inhalt vonAusführliche Erläuterung der Auswahlbeispiele von Redux und Mobx. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn