この記事では、RxJS を使用して React アプリケーションのステータスを管理する方法を紹介します。一定の参考値があり、困っている友人は参照できます。お役に立てれば幸いです。
フロントエンド アプリケーションがますます複雑になるにつれて、アプリケーション データを管理する方法は避けられない問題になっています。複雑なビジネス シナリオ、頻繁な需要の変化、相互に関連し依存するさまざまなアプリケーション データを備えた大規模なフロントエンド アプリケーションに直面した場合、アプリケーションのステータス データをどのように管理しますか? 私たちは、アプリケーション データは大きく 4 つのカテゴリに分類できると考えています:
イベント: 瞬間的に生成されるデータ、データは消費後すぐに破棄され、保存されません。 は当然、非同期プログラムやイベントベースのプログラムを作成するのに適しています。では、状態データをどのように管理するのでしょうか?やはり ##RxJS を使用する必要がありますか?適切ですか?
私たちは、フロントエンド コミュニティですでに利用可能な優れた状態管理ソリューションについて調査して学びました。また、
RxJS
、
Mobx などの関数を完全に実装できます。
アプリケーション データにはステータスだけでなく、イベント、非同期、定数なども含まれます。アプリケーション全体が
observable のシーケンスベースの応答機能を利用して、さまざまな種類のデータをストリーミング方式で自由に接続および結合できます。再利用可能でスケーラブルなビジネス モデルをよりエレガントかつ効率的に実現します。
上記の 2 つの理由により、最終的には 原理導入
は複数の値を持つ集合です。 。
を通じて値を変換して、新しい値を取得できます。
「現在値」という概念がありますが、一般的には現在値、つまり最新の値のみが外部に公開されます。
まず、
自体は複数の値のプッシュ コレクションであるため、最初の条件は満たされます。 #2 番目に、dispatch action
observable を実装できます!ご存知のとおり、
RxJS の
は 2 つのタイプに分類できます。 コールド観察可能
: プッシュされたプロデューサー値 (
) は observable
内から取得されます。 値をいくつプッシュするか、どのような値をプッシュするかは、
observable
プロデューサー
はオブザーバー (
observer
がサブスクライブするたびに、observer
に順番にプッシュします。
hot observable は、外部の observable
から取得されます。 いくつの値がプッシュされるか、どの値がプッシュされるか、いつプッシュされるかは、作成時には不明です。
observer
がサブスクライブするたびに、他のライブラリや言語の observer
がオブザーバー リストに登録されます。
外部 Producer
がトリガーまたは実行されると、値はすべての observer## に同時にプッシュされます。
#hot observable によってプッシュされた値を共有しました。
RxJS
によって提供される ホットオブザーバブル であり、データを外部にプッシュするためのインターフェイスを公開します
next 関数; そして、
observer に送信された最新の値を保存する「現在値」の概念があります。新しいオブザーバーがサブスクライブすると、その値はすぐに
BehaviorSubject から取得されます。 これは「現在の値」を受け取ります。
これは、
BehaviorSubject
を使用して状態を更新し、状態の現在の値を保存することが可能であり、3 番目の条件も満たされていることを示しています。
簡単な実装次のコードを見てください:
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
状態の初期値: 1
実行後の状態値
plus
を使用して状態の現在の値を表現します。
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视频教程】
以上がRxJS を使用して React アプリケーションの状態を管理する方法の概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。