Dieser Artikel bietet Ihnen eine Einführung in die Verwendung von RxJS zum Verwalten des React-Anwendungsstatus. Ich hoffe, dass er für Freunde in Not hilfreich ist.
Da Frontend-Anwendungen immer komplexer werden, ist die Verwaltung von Anwendungsdaten zu einem unvermeidbaren Problem geworden. Wenn Sie mit großen Front-End-Anwendungen mit komplexen Geschäftsszenarien, häufigen Nachfrageänderungen und verschiedenen miteinander verbundenen und abhängigen Anwendungsdaten konfrontiert sind, wie verwalten Sie dann die Statusdaten der Anwendung?
Wir glauben, dass Anwendungsdaten grob in vier Kategorien eingeteilt werden können:
RxJS
eignet sich natürlich zum Schreiben asynchroner und ereignisbasierter Programme. Wie verwaltet man also Zustandsdaten? Sollte ich trotzdem RxJS
verwenden? Ist es geeignet?
Wir haben die vorhandenen hervorragenden Zustandsverwaltungslösungen in der Front-End-Community untersucht und kennengelernt und uns von den Ideen und Praktiken einiger Experten zur Verwendung von RxJS
zum Entwerfen der Datenschicht inspirieren lassen:
RxJS
können Funktionen wie Redux
, Mobx
und andere Verwaltungsstatusdaten vollständig implementiert werden. observable
ausgedrückt wird, können Sie die sequenzbasierten und reaktionsfähigen Funktionen von RxJS
verwenden, um verschiedene Arten von Daten auf fließende Weise frei zu verbinden und zu kombinieren und so mögliche Daten eleganter und effizienter zu abstrahieren Modelle. Aus den beiden oben genannten Gründen haben wir uns schließlich entschieden, eine Lösung zur Verwaltung des Bewerbungsstatus basierend auf RxJS
zu entwickeln.
Einführung in das Prinzip
Für die Definition des Staates wird allgemein angenommen, dass der Staat die folgenden drei Bedingungen erfüllen muss:
event
oder action
umwandeln, um einen neuen Wert zu erhalten. Ist RxJS
also für die Verwaltung von Statusdaten geeignet? Die Antwort ist ja!
Da Observable
selbst eine Push-Sammlung mehrerer Werte ist, ist zunächst einmal die erste Bedingung erfüllt!
Zweitens können wir ein dispatch action
implementieren, das das observable
-Muster verwendet, um Daten zu pushen, um die zweite Bedingung zu erfüllen
Wie wir alle wissen , RxJS in > kann in zwei Typen unterteilt werden: observable
: Der Produzent (cold observable
), der den Wert treibt, kommt von innen producer
. Wie viele Werte observable
observable
producer
), die unicast ist. observer
observer
nacheinander mehrere vordefinierte Werte an producer
übertragen. observer
: Wert hot observable
von außen producer
pushen. Wie viele Werte observable
producer
haben eine Eins-zu-Viele-Beziehung, also Multicast. observer
observer
in der Beobachterliste registriert, ähnlich wie observer
in anderen Bibliotheken oder Sprachen funktioniert. addListener
producer
gleichzeitig übertragen; das heißt, alle observer
teilen den von observer
übertragenen Wert. Das von hot observable
bereitgestellte RxJS
ist eine besondere Art von BehaviorSubject
, das die Schnittstelle hot observable
zum Übertragen von Daten verfügbar macht und über das Konzept des „aktuellen Werts“ verfügt Der zuletzt an next
gesendete Wert wird gespeichert. Wenn sich ein neuer Beobachter anmeldet, wird der „aktuelle Wert“ sofort von observer
empfangen. BehaviorSubject
Dann zeigt dies, dass es möglich ist, zu verwenden, um den Status zu aktualisieren und den aktuellen Wert des Status zu speichern, und die dritte Bedingung ist ebenfalls erfüllt. BehaviorSubject
import { BehaviorSubject } from 'rxjs'; // 数据推送的生产者 class StateMachine { constructor(subject, value) { this.subject = subject; this.value = value; } producer(action) { let oldValue = this.value; let newValue; switch (action.type) { case 'plus': newValue = ++oldValue; this.value = newValue; this.subject.next(newValue); break; case 'toDouble': newValue = oldValue * 2; this.value = newValue; this.subject.next(newValue); break; } } } const value = 1; // 状态的初始值 const count$ = new BehaviorSubject(value); const stateMachine = new StateMachine(count$, value); // 派遣action function dispatch(action) { stateMachine.producer(action); } count$.subscribe(val => { console.log(val); }); setTimeout(() => { dispatch({ type: "plus" }); }, 1000); setTimeout(() => { dispatch({ type: "toDouble" }); }, 2000);
Console 1 2 4
plus
toDouble
dispatch
函数使producer
函数执行producer
函数在内部调用了BehaviorSubject
的next
函数,推送了新数据,BehaviorSubject
的当前值更新了,也就是状态更新了。不过写起来略微繁琐,我们对其进行了封装,优化后写法见下文。
我们自定义了一个操作符state
用来创建一个能够通过dispatch action
模式推送新数据的BehaviorSubject
,我们称她为stateObservable
。
const count$ = state({ // 状态的唯一标识名称 name: "count", // 状态的默认值 defaultValue: 1, // 数据推送的生产者函数 producer(next, value, action) { switch (action.type) { case "plus": next(value + 1); break; case "toDouble": next(value * 2); break; } } });
在你想要的任意位置使用函数dispatch
派遣action
即可更新状态!
dispatch("count", { type: "plus" })
RxJS
的一大优势就在于能够统一同步和异步,使用observable
处理数据你不需要关注同步还是异步。
下面的例子我们使用操作符from
将promise
转换为observable
。
observable
作为状态的初始值(首次推送数据)const todos$ = state({ name: "todos", // `observable`推送的数据将作为状态的初始值 initial: from(getAsyncData()) //... });
producer
推送observable
const todos$ = state({ name: "todos", defaultValue: [] // 数据推送的生产者函数 producer(next, value, action) { switch (action.type) { case "getAsyncData": next( from(getAsyncData()) ); break; } } });
执行getAsyncData
之后,from(getAsyncData())
的推送数据将成为状态的最新值。
由于状态todos$
是一个observable
,所以可以很自然地使用RxJS
操作符转换得到另一个新的observable
。并且这个observable
的推送来自todos$
;也就是说只要todos$
推送新数据,它也会推送;效果类似于Vue
的计算属性。
// 未完成任务数量 const undoneCount$ = todos$.pipe( map(todos => { let _conut = 0; todos.forEach(item => { if (!item.check) ++_conut; }); return _conut; }) );
我们可能会在组件的生命周期内订阅observable
得到数据渲染视图。
class Todos extends React.Component { componentWillMount() { todos$.subscribe(data => { this.setState({ todos: data }); }); } }
我们可以再优化下,利用高阶组件封装一个装饰器函数@subscription
,顾名思义,就是为React组件订阅observable
以响应推送数据的变化;它会将observable
推送的数据转换为React组件的props
。
@subscription({ todos: todos$ }) class TodoList extends React.Component { render() { return ( <p className="todolist"> <h1 className="header">任务列表</h1> {this.props.todos.map((item, n) => { return <TodoItem item={item} key={item.desc} />; })} </p> ); } }
使用RxJS
越久,越令人受益匪浅。
observable
序列提供了较高层次的抽象,并且是观察者模式,可以尽可能地减少各组件各模块之间的耦合度,大大减轻了定位BUG和重构的负担。observable
序列来编写代码的,所以遇到复杂的业务场景,总能按照一定的顺序使用observable
描述出来,代码的可读性很强。并且当需求变动时,我可能只需要调整下observable
的顺序,或者加个操作符就行了。再也不必因为一个复杂的业务流程改动了,需要去改好几个地方的代码(而且还容易改出BUG,笑~)。所以,以上基于RxJS
的状态管理方案,对我们来说是一个必需品,因为我们项目中大量使用了RxJS
,如果状态数据也是observable
,对我们抽象可复用可扩展的业务模型是一个非常大的助力。当然了,如果你的项目中没有使用RxJS
,也许Redux
和Mobx
是更合适的选择。
这套基于RxJS
的状态管理方案,我们已经用于开发公司的商用项目,反馈还不错。所以我们决定把这套方案整理成一个js lib
,取名为:Floway
,并在github
上开源:
【相关推荐:react视频教程】
Das obige ist der detaillierte Inhalt vonEine Einführung in die Verwendung von RxJS zum Verwalten des React-Anwendungsstatus. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!