简体   繁体   English

套接字在哪里适合Flux单向数据流?

[英]Where do sockets fit into the Flux unidirectional data flow?

Where do sockets fit into the Flux unidirectional data flow? 套接字在哪里适合Flux单向数据流? I have read 2 schools of thought for where remote data should enter the Flux unidirectional data flow. 我已经阅读了两种思路,即远程数据应该进入Flux单向数据流。 The way I have seen remote data for a Flux app fetched is when a server-side call is made, for example, in a promise that is then resolved or rejected. 我看到获取Flux应用程序的远程数据的方式是在进行服务器端调用时,例如,在承诺中解析或拒绝。 Three possible actions could fire during this process: 在此过程中可能会触发三种可能的操作:

  1. An initial action for optimistically updating the view (FooActions.BAR) 乐观更新视图的初始操作(FooActions.BAR)
  2. A success action for when an asynchronous promise is resolved (FooActions.BAR_SUCCESS) 解决异步承诺时的成功操作(FooActions.BAR_SUCCESS)
  3. An error action for when an asynchronous promise is rejected (FooActions.BAR_ERROR) 异步承诺被拒绝时的错误操作(FooActions.BAR_ERROR)

The stores will listen for the actions and update the necessary data. 商店将监听操作并更新必要的数据。 I have seen the server-side calls made from both action creators and from within the stores themselves. 我已经看到了来自动作创建者和商店内部的服务器端调用。 I use action creators for the process described above, but I'm not sure if data fetching via a web socket should be treated similarly. 我使用动作创建器进行上述过程,但我不确定是否应该通过Web套接字获取数据。 I was wondering where sockets fit into the diagram below. 我想知道插座适合下图。

在此输入图像描述

There's really no difference in how you use Flux with WebSockets or plain old HTTP requests/polling. 使用Flux与WebSockets或普通的旧HTTP请求/轮询的方式确实没有区别。 Your stores are responsible for emitting a change event when the application state changes, and it shouldn't be visible from the outside of the store if that change came from a UI interaction, from a WebSocket, or from making an HTTP request. 您的商店负责在应用程序状态更改时发出更改事件,如果该更改来自UI交互,WebSocket或发出HTTP请求,则不应从商店外部看到它。 That's really one of the main benefits of Flux in that no matter where the application state was changed, it goes through the same code paths. 这实际上是Flux的主要优点之一,无论应用程序状态在何处发生变化,它都会经历相同的代码路径。

Some Flux implementations tend to use actions/action creators for fetching data, but I don't really agree with that. 一些Flux实现倾向于使用动作/动作创建器来获取数据,但我不同意这一点。

Actions are things that happen that modifies your application state. 操作是发生修改应用程序状态的事情。 It's things like "the user changed some text and hit save" or "the user deleted an item". 这就是“用户更改了一些文本并点击保存”或“用户删除了一个项目”。 Think of actions like the transaction log of a database. 想想像数据库的事务日志这样的操作。 If you lost your database, but you saved and serialized all actions that ever happened, you could just replay all those actions and end up with the same state/database that you lost. 如果丢失了数据库,但保存并序列化了所有发生的操作,则可以重放所有这些操作,最终得到丢失的相同状态/数据库。

So things like "give me item with id X" and "give me all the items" aren't actions, they're questions, questions about that application state. 所以像“给我带有身份X的项目”和“给我所有项目”这样的事情不是行动,而是问题,关于该申请状态的问题。 And in my view, it's the stores that should respond to those questions via methods that you expose on those stores. 在我看来,这些商店应该通过您在这些商店中公开的方法来回应这些问题。

It's tempting to use actions/action creators for fetching because fetching needs to be async. 使用动作/动作创建器进行提取很诱人,因为提取需要异步。 And by wrapping the async stuff in actions, your components and stores can be completely synchronous. 通过将异步内容包装在操作中,您的组件和存储可以完全同步。 But if you do that, you blur the definition of what an action is, and it also forces you to assume that you can fit your entire application state in memory (because you can only respond synchronously if you have the answer in memory). 但是,如果你这样做,你会模糊一个动作的定义,它也会强迫你假设你可以将整个应用程序状态放在内存中(因为你只能在内存中得到答案时才能同步响应)。

So here's how I view Flux and the different concepts. 所以这就是我如何看待Flux和不同的概念。

Stores 商店

This is obviously where your application state lives. 这显然是您的应用程序状态所在的位置。 The store encapsulates and manages the state and is the only place where mutation of that state actually happens. 商店封装和管理状态,是该状态实际发生突变的唯一地方。 It's also where events are emitted when that state changes. 它也是当状态发生变化时发出事件的地方。

The stores are also responsible for communicating with the backend. 商店还负责与后端通信。 The store communicates with the backend when the state has changed and that needs to be synced with the server, and it also communicates with the server when it needs data that it doesn't have in memory. 当状态发生变化并且需要与服务器同步时,商店与后端通信,并且当它需要内存中没有的数据时,它还与服务器通信。 It has methods like get(id) , search(parameters) etc. Those methods are for your questions, and they all return promises, even if the state can fit into memory. 它有get(id)search(parameters)等方法。这些方法都是针对你的问题,它们都返回了promises,即使状态可以适应内存。 That's important because you might end up with use cases where the state no longer fits in memory, or where it's not possible to filter in memory or do advanced searching. 这很重要,因为您最终可能会遇到状态不再适合内存的情况,或者无法在内存中进行过滤或进行高级搜索的情况。 By returning promises from your question methods, you can switch between returning from memory or asking the backend without having to change anything outside of the store. 通过从您的问题方法返回promise,您可以在从内存返回或询问后端之间切换,而无需更改商店外的任何内容。

Actions 操作

My actions are very lightweight, and they don't know anything about persisting the mutation that they encapsulate. 我的行为非常轻量级,并且他们对持久化它们所包含的突变一无所知。 They simply carry the intention to mutate from the component to the store. 他们只是意图从组件变异到商店。 For larger applications, they can contain some logic, but never things like server communication. 对于较大的应用程序,它们可以包含一些逻辑,但绝不会包含服务器通信。

Components 组件

These are your React components. 这些是您的React组件。 They interact with stores by calling the question methods on the stores and rendering the return value of those methods. 它们通过调用商店中的问题方法并呈现这些方法的返回值来与商店进行交互。 They also subscribe to the change event that the store exposes. 他们还订阅了商店公开的change事件。 I like using higher order components which are components that just wrap another component and passes props to it. 我喜欢使用更高阶的组件 ,这些组件只是包装另一个组件并将props传递给它。 An example would be: 一个例子是:

var TodoItemsComponent = React.createClass({
  getInitialState: function () {
    return {
      todoItems: null
    }
  },
  componentDidMount: function () {
    var self = this;
    TodoStore.getAll().then(function (todoItems) {
      self.setState({todoItems: todoItems});
    });

    TodoStore.onChange(function (todoItems) {
      self.setState({todoItems: todoItems});
    });
  },
  render: function () {
    if (this.state.todoItems) {
      return <TodoListComponent todoItems={this.state.todoItems} />;
    } else {
      return <Spinner />;
    }
  }
});

var TodoListComponent = React.createClass({
  createNewTodo: function () {
    TodoActions.createNew({
      text: 'A new todo!'
    });
  },
  render: function () {
    return (
      <ul>
        {this.props.todoItems.map(function (todo) {
          return <li>{todo.text}</li>;
        })}
      </ul>
      <button onClick={this.createNewTodo}>Create new todo</button>
    );
  }
});

In this example the TodoItemsComponent is the higher order component and it wraps the nitty-gritty details of communicating with the store. 在这个例子中, TodoItemsComponent是更高阶的组件,它包含了与商店通信的细节。 It renders the TodoListComponent when it has fetched the todos, and renders a spinner before that. 它在获取TodoListComponent时呈现TodoListComponent ,并在此之前呈现一个微调器。 Since it passes the todo items as props to TodoListComponent that component only has to focus on rendering, and it will be re-rendered as soon as anything changes in the store. 因为它将todo项目作为道具传递给TodoListComponent ,组件只需要专注于渲染,并且只要存储中的任何更改,它就会被重新渲染。 And the rendering component is kept completely synchronous. 并且渲染组件保持完全同步。 Another benefit is that TodoItemsComponent is only focused on fetching data and passing it on, making it very reusable for any rendering component that needs the todos. 另一个好处是TodoItemsComponent只专注于获取数据并将其传递,使其对任何需要todos的渲染组件都非常可重用。

higher order components 更高阶的组件

The term higher order components comes from the term higher order functions. 术语高阶分量来自术语高阶函数。 Higher order functions are functions that return other functions. 高阶函数是返回其他函数的函数。 So a higher order component is a component that just wraps another component and returns its output. 因此,更高阶的组件是一个只包装另一个组件并返回其输出的组件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM