Maison >interface Web >Questions et réponses frontales >Que signifie flux en réaction ?

Que signifie flux en réaction ?

青灯夜游
青灯夜游original
2021-11-25 12:16:491779parcourir

In React, Flux est une solution de gestion de l'état public, utilisée pour construire l'architecture d'application des applications Web côté client et gérer l'état public sous la forme d'un flux de données unidirectionnel.

Que signifie flux en réaction ?

L'environnement d'exploitation de ce tutoriel : système Windows 7, React version 17.0.1, ordinateur Dell G3.

Qu'est-ce que flux

flux est une solution de gestion d'état publique similaire à vuex in React. Il s'agit de l'architecture d'application officiellement donnée par Facebook pour créer des applications Web clientes, en utilisant le flux de données unidirectionnel Gérer. statut public sous la forme de

.

Cela ressemble plus à un modèle qu'à un cadre formel. Les développeurs peuvent rapidement démarrer avec Flux sans avoir besoin de trop de nouveau code.

cnpm i flux -S 的方式进行安装。

flux的组成

  • View:视图层

  • Action:视图发出的消息

  • Dispatcher:派发者,用来接收Action,执行回调函数

  • Store:数据层,存放状态,一旦发生改动,

Que signifie flux en réaction ?
flux的工作流程

Flux 的最大特点,就是数据的"单向流动"。

  • 用户访问 View

  • View 发出用户的 Action

  • Dispatcher 收到 Action,要求 Store 进行相应的更新

  • Store 更新后,发出一个"change"事件

  • View 收到"change"事件后,更新页面

上面过程中,数据总是"单向流动",任何相邻的部分都不会发生数据的"双向流动"。这保证了流程的清晰。

读到这里,你可能感到一头雾水,OK,这是正常的。接下来,我会详细讲解每一步。

View(第一部分)

请打开 Demo 的首页index.jsx ,你会看到只加载了一个组件。

// index.jsx
var React = require('react');
var ReactDOM = require('react-dom');
var MyButtonController = require('./components/MyButtonController');

ReactDOM.render(
  <MyButtonController/>,
  document.querySelector(&#39;#example&#39;)
);

上面代码中,你可能注意到了,组件的名字不是 MyButton,而是 MyButtonController。这是为什么?

这里,我采用的是 React 的 controller view 模式。"controller view"组件只用来保存状态,然后将其转发给子组件。MyButtonController的源码很简单。

// components/MyButtonController.jsx
var React = require(&#39;react&#39;);
var ButtonActions = require(&#39;../actions/ButtonActions&#39;);
var MyButton = require(&#39;./MyButton&#39;);

var MyButtonController = React.createClass({
  createNewItem: function (event) {
    ButtonActions.addNewItem(&#39;new item&#39;);
  },

  render: function() {
    return <MyButton
      onClick={this.createNewItem}
    />;
  }
});

module.exports = MyButtonController;

上面代码中,MyButtonController将参数传给子组件MyButton。后者的源码甚至更简单。

// components/MyButton.jsx
var React = require(&#39;react&#39;);

var MyButton = function(props) {
  return <div>
    <button onClick={props.onClick}>New Item</button>
  </div>;
};

module.exports = MyButton;

上面代码中,你可以看到MyButton是一个纯组件(即不含有任何状态),从而方便了测试和复用。这就是"controll view"模式的最大优点。

MyButton只有一个逻辑,就是一旦用户点击,就调用this.createNewItem 方法,向Dispatcher发出一个Action。

// components/MyButtonController.jsx

  // ...
  createNewItem: function (event) {
    ButtonActions.addNewItem(&#39;new item&#39;);
  }

上面代码中,调用createNewItem方法,会触发名为addNewItem的Action。

Action

每个Action都是一个对象,包含一个actionType属性(说明动作的类型)和一些其他属性(用来传递数据)。

在这个Demo里面,ButtonActions 对象用于存放所有的Action。

// actions/ButtonActions.js
var AppDispatcher = require(&#39;../dispatcher/AppDispatcher&#39;);

var ButtonActions = {
  addNewItem: function (text) {
    AppDispatcher.dispatch({
      actionType: &#39;ADD_NEW_ITEM&#39;,
      text: text
    });
  },
};

上面代码中,ButtonActions.addNewItem方法使用AppDispatcher,把动作ADD_NEW_ITEM派发到Store。

Dispatcher

Dispatcher 的作用是将 Action 派发到 Store、。你可以把它看作一个路由器,负责在 View 和 Store 之间,建立 Action 的正确传递路线。注意,Dispatcher 只能有一个,而且是全局的。

Facebook官方的 Dispatcher 实现输出一个类,你要写一个AppDispatcher.js,生成 Dispatcher 实例。

// dispatcher/AppDispatcher.js
var Dispatcher = require(&#39;flux&#39;).Dispatcher;
module.exports = new Dispatcher();

AppDispatcher.register()方法用来登记各种Action的回调函数。

// dispatcher/AppDispatcher.js
var ListStore = require(&#39;../stores/ListStore&#39;);

AppDispatcher.register(function (action) {
  switch(action.actionType) {
    case &#39;ADD_NEW_ITEM&#39;:
      ListStore.addNewItemHandler(action.text);
      ListStore.emitChange();
      break;
    default:
      // no op
  }
})

上面代码中,Dispatcher收到ADD_NEW_ITEM动作,就会执行回调函数,对ListStore进行操作。

记住,Dispatcher 只用来派发 Action,不应该有其他逻辑。

Store

Store 保存整个应用的状态。它的角色有点像 MVC 架构之中的Model 。

在我们的 Demo 中,有一个ListStore,所有数据都存放在那里。

// stores/ListStore.js
var ListStore = {
  items: [],

  getAll: function() {
    return this.items;
  },

  addNewItemHandler: function (text) {
    this.items.push(text);
  },

  emitChange: function () {
    this.emit(&#39;change&#39;);
  }
};

module.exports = ListStore;

上面代码中,ListStore.items用来保存条目,ListStore.getAll()用来读取所有条目,ListStore.emitChange()Utilisez cnpm i flux -S pour installer.

🎜Composition du flux 🎜🎜🎜
  • 🎜Vue : calque de vue🎜
  • 🎜Action : message envoyé par la vue🎜
  • 🎜Dispatcher : Dispatcher, utilisé pour recevoir des actions et exécuter des fonctions de rappel🎜
  • 🎜Store : couche de données, état de stockage, une fois que des changements se produisent,🎜
Que signifie flux en réaction ?
Le flux de travail de Flux🎜🎜La plus grande fonctionnalité de Flux est le "flux unidirectionnel" des données. 🎜
  • 🎜L'utilisateur accède à View🎜
  • 🎜Afficher les problèmes d'action de l'utilisateur🎜
  • 🎜Le répartiteur reçoit une action, nécessitant le Store se met à jour en conséquence🎜
  • 🎜Une fois le Store mis à jour, il envoie un événement "changement"🎜
  • 🎜View met à jour la page après avoir reçu l'événement "change"🎜 li >
🎜Dans le processus ci-dessus, les données « circulent toujours dans une direction » et le « flux bidirectionnel » de données ne se produira dans aucune partie adjacente. Cela garantit la clarté du processus. 🎜🎜Après avoir lu ceci, vous pourriez vous sentir confus, OK, c'est normal. Ensuite, j'expliquerai chaque étape en détail. 🎜

Affichage (Partie 1)

🎜Veuillez ouvrir la page d'accueil de la démo index.jsx et vous verrez qu'un seul composant est chargé. 🎜
// stores/ListStore.js
var EventEmitter = require(&#39;events&#39;).EventEmitter;
var assign = require(&#39;object-assign&#39;);

var ListStore = assign({}, EventEmitter.prototype, {
  items: [],

  getAll: function () {
    return this.items;
  },

  addNewItemHandler: function (text) {
    this.items.push(text);
  },

  emitChange: function () {
    this.emit(&#39;change&#39;);
  },

  addChangeListener: function(callback) {
    this.on(&#39;change&#39;, callback);
  },

  removeChangeListener: function(callback) {
    this.removeListener(&#39;change&#39;, callback);
  }
});
🎜Dans le code ci-dessus, vous avez peut-être remarqué que le nom du composant n'est pas MyButton, mais MyButtonController. pourquoi donc? 🎜🎜Ici, j'utilise le mode d'affichage du contrôleur de React. Le composant « vue du contrôleur » est uniquement utilisé pour enregistrer l'état, puis le transmettre aux composants enfants. Le code source de MyButtonController est très simple. 🎜
// components/MyButtonController.jsx
var React = require(&#39;react&#39;);
var ListStore = require(&#39;../stores/ListStore&#39;);
var ButtonActions = require(&#39;../actions/ButtonActions&#39;);
var MyButton = require(&#39;./MyButton&#39;);

var MyButtonController = React.createClass({
  getInitialState: function () {
    return {
      items: ListStore.getAll()
    };
  },

  componentDidMount: function() {
    ListStore.addChangeListener(this._onChange);
  },

  componentWillUnmount: function() {
    ListStore.removeChangeListener(this._onChange);
  },

  _onChange: function () {
    this.setState({
      items: ListStore.getAll()
    });
  },

  createNewItem: function (event) {
    ButtonActions.addNewItem(&#39;new item&#39;);
  },

  render: function() {
    return <MyButton
      items={this.state.items}
      onClick={this.createNewItem}
    />;
  }
});
🎜Dans le code ci-dessus, MyButtonController transmet les paramètres au sous-composant MyButton. Le code source de ce dernier est encore plus simple. 🎜
// components/MyButton.jsx
var React = require(&#39;react&#39;);

var MyButton = function(props) {
  var items = props.items;
  var itemHtml = items.map(function (listItem, i) {
    return <li key={i}>{listItem}</li>;
  });

  return <div>
    <ul>{itemHtml}</ul>
    <button onClick={props.onClick}>New Item</button>
  </div>;
};

module.exports = MyButton;
🎜Dans le code ci-dessus, vous pouvez voir que MyButton est un composant pur (c'est-à-dire qu'il ne contient aucun état), ce qui facilite les tests et la réutilisation. C'est le plus gros avantage du mode "control view". 🎜🎜MyButton n'a qu'une seule logique, qui consiste à appeler la méthode this.createNewItem une fois que l'utilisateur clique dessus et à envoyer une action au répartiteur. 🎜rrreee🎜Dans le code ci-dessus, l'appel de la méthode createNewItem déclenchera une action nommée addNewItem. 🎜

Action

🎜Chaque action est un objet, contenant un attribut actionType (décrivant le type d'action) et quelques autres attributs (utilisés pour transmettre des données). 🎜🎜Dans cette démo, l'objet ButtonActions est utilisé pour stocker toutes les actions. 🎜rrreee🎜Dans le code ci-dessus, la méthode ButtonActions.addNewItem utilise AppDispatcher pour envoyer l'action ADD_NEW_ITEM au Store. 🎜

Dispatcher

🎜La fonction de Dispatcher est d'envoyer l'action au magasin. Vous pouvez le considérer comme un routeur, chargé d'établir l'itinéraire de livraison correct pour les actions entre View et Store. Notez qu’il ne peut y avoir qu’un seul Dispatcher et qu’il est global. 🎜🎜 L'implémentation officielle de Dispatcher de Facebook génère une classe. Vous devez écrire un AppDispatcher.js pour générer une instance de Dispatcher. La méthode 🎜rrreee🎜AppDispatcher.register() est utilisée pour enregistrer diverses fonctions de rappel d'action. 🎜rrreee🎜Dans le code ci-dessus, lorsque Dispatcher reçoit l'action ADD_NEW_ITEM, il exécutera la fonction de rappel et exploitera ListStore. 🎜🎜N'oubliez pas que Dispatcher n'est utilisé que pour distribuer des actions et ne devrait pas avoir d'autre logique. 🎜

Store

🎜Store enregistre l'état de l'ensemble de l'application. Son rôle est un peu comme Model dans l’architecture MVC. 🎜🎜Dans notre démo, il existe un ListStore où toutes les données sont stockées. 🎜rrreee🎜Dans le code ci-dessus, ListStore.items est utilisé pour enregistrer les éléments, ListStore.getAll() est utilisé pour lire tous les éléments, ListStore.emitChange( ) est utilisé pour émettre un événement "change". 🎜🎜Étant donné que le Store doit envoyer l'événement "change" à la View après le changement, il doit implémenter l'interface d'événement. 🎜<pre class="brush:js;toolbar:false;">// stores/ListStore.js var EventEmitter = require(&amp;#39;events&amp;#39;).EventEmitter; var assign = require(&amp;#39;object-assign&amp;#39;); var ListStore = assign({}, EventEmitter.prototype, { items: [], getAll: function () { return this.items; }, addNewItemHandler: function (text) { this.items.push(text); }, emitChange: function () { this.emit(&amp;#39;change&amp;#39;); }, addChangeListener: function(callback) { this.on(&amp;#39;change&amp;#39;, callback); }, removeChangeListener: function(callback) { this.removeListener(&amp;#39;change&amp;#39;, callback); } });</pre><p>上面代码中,<code>ListStore继承了EventEmitter.prototype,因此就能使用ListStore.on()ListStore.emit(),来监听和触发事件了。

Store 更新后(this.addNewItemHandler())发出事件(this.emitChange()),表明状态已经改变。 View 监听到这个事件,就可以查询新的状态,更新页面了。

View (第二部分)

现在,我们再回过头来修改 View ,让它监听 Store 的 change 事件。

// components/MyButtonController.jsx
var React = require(&#39;react&#39;);
var ListStore = require(&#39;../stores/ListStore&#39;);
var ButtonActions = require(&#39;../actions/ButtonActions&#39;);
var MyButton = require(&#39;./MyButton&#39;);

var MyButtonController = React.createClass({
  getInitialState: function () {
    return {
      items: ListStore.getAll()
    };
  },

  componentDidMount: function() {
    ListStore.addChangeListener(this._onChange);
  },

  componentWillUnmount: function() {
    ListStore.removeChangeListener(this._onChange);
  },

  _onChange: function () {
    this.setState({
      items: ListStore.getAll()
    });
  },

  createNewItem: function (event) {
    ButtonActions.addNewItem(&#39;new item&#39;);
  },

  render: function() {
    return <MyButton
      items={this.state.items}
      onClick={this.createNewItem}
    />;
  }
});

上面代码中,你可以看到当MyButtonController 发现 Store 发出 change 事件,就会调用 this._onChange 更新组件状态,从而触发重新渲染。

// components/MyButton.jsx
var React = require(&#39;react&#39;);

var MyButton = function(props) {
  var items = props.items;
  var itemHtml = items.map(function (listItem, i) {
    return <li key={i}>{listItem}</li>;
  });

  return <div>
    <ul>{itemHtml}</ul>
    <button onClick={props.onClick}>New Item</button>
  </div>;
};

module.exports = MyButton;

推荐学习:《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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn