Cet article vous présente une introduction à l'utilisation de RxJS pour gérer le statut des applications React. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il vous sera utile.
À mesure que les applications frontales deviennent de plus en plus complexes, la gestion des données des applications est devenue un problème inévitable. Lorsque vous êtes confronté à des applications frontales à grande échelle avec des scénarios commerciaux complexes, des changements fréquents de la demande et diverses données d'application interdépendantes et dépendantes , comment allez-vous gérer les données d'état de l'application ?
Nous pensons que les données des applications peuvent être grossièrement divisées en quatre catégories :
RxJS
est naturellement adapté à l'écriture de programmes asynchrones et basés sur des événements, alors comment gérer les données d'état ? Dois-je quand même utiliser RxJS
? Est-ce adapté ?
Nous avons étudié et découvert les excellentes solutions de gestion d'état existantes dans la communauté front-end, et nous avons été inspirés par les idées et les pratiques partagées par certains experts sur l'utilisation de RxJS
pour concevoir la couche de données :
RxJS
peut complètement implémenter des fonctions telles que Redux
, Mobx
et d'autres données d'état de gestion. observable
, vous pouvez utiliser les fonctionnalités réactives et basées sur des séquences de RxJS
pour assembler et combiner librement différents types de données de manière fluide, en extrayant les données possibles de manière plus élégante et plus efficace. modèles. Pour les deux raisons ci-dessus, nous avons finalement décidé de concevoir une solution de gestion du statut des candidatures basée sur RxJS
.
Introduction au principe
Pour la définition de l'État, on pense généralement que l'État doit remplir les trois conditions suivantes :
event
ou action
pour obtenir une nouvelle valeur. Alors, RxJS
est-il adapté à la gestion des données de statut ? La réponse est oui !
Tout d'abord, parce que Observable
lui-même est une collection push de plusieurs valeurs, la première condition est remplie !
Deuxièmement, nous pouvons implémenter un dispatch action
qui utilise le modèle observable
pour pousser les données afin de satisfaire la deuxième condition
Comme nous le savons tous ! , RxJS in > peut être divisé en deux types : observable
: Le producteur (cold observable
) qui pousse la valeur vient de l'intérieur producer
. Le nombre de valeurs observable
observable
producer
), qui est en monodiffusion. observer
observer
poussera plusieurs valeurs prédéfinies vers producer
dans l'ordre. observer
: Poussez la valeur hot observable
de l'extérieur producer
. observable
producer
ont une relation un-à-plusieurs, c'est-à-dire multidiffusion. observer
observer
sera enregistré dans la liste des observateurs, de la même manière que observer
fonctionne dans d'autres bibliothèques ou langues. addListener
producer
en même temps ; c'est-à-dire que tous les observer
partagent la valeur poussée par observer
. Le hot observable
fourni par RxJS
est un type spécial de BehaviorSubject
, qui expose la fonction d'interface hot observable
pour pousser les données et a le concept de « valeur actuelle » ; La dernière valeur envoyée à next
est enregistrée Lorsqu'un nouvel observateur s'abonne, la "valeur actuelle" sera immédiatement reçue de observer
. BehaviorSubject
Ensuite, cela montre qu'il est possible d'utiliser pour mettre à jour l'état et enregistrer la valeur actuelle de l'état, et la troisième condition est également remplie. 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
pour exprimer la valeur actuelle du statut : BehaviorSubject
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视频教程】
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!