Heim  >  Artikel  >  Web-Frontend  >  Eine Einführung in die Verwendung von RxJS zum Verwalten des React-Anwendungsstatus

Eine Einführung in die Verwendung von RxJS zum Verwalten des React-Anwendungsstatus

不言
不言nach vorne
2019-04-03 10:24:592825Durchsuche

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:

  • Ereignisse: Daten, die sofort generiert werden. Die Daten werden sofort nach dem Verbrauch zerstört und nicht gespeichert.
  • Asynchron: Daten werden asynchron abgerufen; ähnlich wie bei Ereignissen handelt es sich um sofortige Daten, die nicht gespeichert werden.
  • Status: Daten, die sich zeitlich und räumlich ändern, speichern immer einen aktuellen/letzten Wert.
  • Konstante: feste Daten.

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:

  1. Mit RxJS können Funktionen wie Redux, Mobx und andere Verwaltungsstatusdaten vollständig implementiert werden.
  2. Bei den Anwendungsdaten handelt es sich nicht nur um Status, sondern auch um Ereignisse, asynchrone Ereignisse, Konstanten usw. Wenn die gesamte Anwendung durch 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:

  1. ist eine Menge mit mehreren Werten .
  2. kann den Wert über event oder action umwandeln, um einen neuen Wert zu erhalten.
  3. Es gibt das Konzept des „aktuellen Werts“. Im Allgemeinen wird nur der aktuelle Wert, also der aktuelle Wert, der Außenwelt ausgesetzt.

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

    gepusht werden und welche Art von Werten gepusht werden, wurde bei der Erstellung von
  • definiert und kann nicht geändert werden. observable
  • hat eine Eins-zu-eins-Beziehung mit dem Beobachter (producer), die unicast ist. observer
  • Immer wenn ein
  • -Abonnement besteht, wird observer nacheinander mehrere vordefinierte Werte an producer übertragen. observer

: Wert hot observable von außen producer pushen. Wie viele Werte observable

    gepusht werden, welche Werte wann gepusht werden, ist zum Zeitpunkt der Erstellung unbekannt.
  • und producer haben eine Eins-zu-Viele-Beziehung, also Multicast. observer
  • Immer wenn ein
  • -Abonnement besteht, wird observer in der Beobachterliste registriert, ähnlich wie observer in anderen Bibliotheken oder Sprachen funktioniert. addListener
  • Wenn das externe
  • ausgelöst oder ausgeführt wird, wird der Wert an alle 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

Einfache Implementierung

Bitte schauen Sie sich den folgenden Code an:

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);
Beim Ausführen der Codekonsole werden drei Werte ausgedruckt:

Console

 1
 2
 4
Das Obige Der Code implementiert einfach ein Beispiel für eine einfache Zustandsverwaltung:

    Anfangswert des Zustands: 1
  • Zustandswert nach Ausführung von
  • : 2plus
  • Ausführung: 4
  • toDouble
  • Die Implementierungsmethode ist recht einfach, das heißt, Sie verwenden
, um den aktuellen Statuswert auszudrücken:

  • 第一步,通过调用dispatch函数使producer函数执行
  • 第二部,producer函数在内部调用了BehaviorSubjectnext函数,推送了新数据,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处理数据你不需要关注同步还是异步。

下面的例子我们使用操作符frompromise转换为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;
  })
);

React视图渲染

我们可能会在组件的生命周期内订阅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,也许ReduxMobx是更合适的选择。

这套基于RxJS的状态管理方案,我们已经用于开发公司的商用项目,反馈还不错。所以我们决定把这套方案整理成一个js lib,取名为:Floway,并在github上开源:

  • github源码:https://github.com/shayeLee/floway
  • 使用文档:https://shayelee.github.io/floway

【相关推荐: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!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen