套接字在哪里适合 Flux 单向数据流?
Where do sockets fit into the Flux unidirectional data flow?
套接字适合Flux单向数据流的什么地方?关于远程数据应从何处进入 Flux 单向数据流,我阅读了两种观点。我看到 Flux 应用程序获取远程数据的方式是在进行服务器端调用时,例如,在随后被解决或拒绝的承诺中。在此过程中可能会触发三种可能的操作:
- 乐观更新视图的初始操作
(FooActions.BAR)
- 解决异步承诺时的成功操作
(FooActions.BAR_SUCCESS)
- 拒绝异步承诺时的错误操作
(FooActions.BAR_ERROR)
商店将侦听操作并更新必要的数据。我已经看到动作创建者和商店本身发出的服务器端调用。我在上述过程中使用了 action creators,但我不确定是否应该对通过 web 套接字获取的数据进行类似处理。我想知道套接字在下图中的位置。
将 Flux 与 WebSockets 或普通的旧 HTTP requests/polling 结合使用的方式确实没有区别。您的商店负责在应用程序状态更改时发出更改事件,如果该更改来自 UI 交互、WebSocket 或创建 HTTP,则从商店外部不应该看到该事件要求。这确实是 Flux 的主要优势之一,因为无论应用程序状态在何处更改,它都会通过相同的代码路径。
一些 Flux 实现倾向于使用 actions/action creators 来获取数据,但我不太同意。
操作是修改应用程序状态的事情。类似于 "the user changed some text and hit save" 或 "the user deleted an item"。将操作想象成数据库的事务日志。如果你丢失了你的数据库,但是你保存并序列化了所有曾经发生的动作,你可以重放所有这些动作并以你丢失的相同 state/database 结束。
所以 "give me item with id X" 和 "give me all the items" 之类的东西不是操作,它们是问题,是关于应用程序状态的问题。在我看来,商店应该通过您在这些商店中公开的方法来回答这些问题。
很想使用 actions/action creators 来获取,因为获取需要异步。通过将异步内容包装在操作中,您的组件和商店可以完全同步。但如果你这样做,你就模糊了动作的定义,而且它还迫使你假设你可以将整个应用程序状态放入内存(因为只有在内存中有答案时你才能同步响应)。
下面是我对 Flux 和不同概念的看法。
商店
这显然是您的应用程序状态所在的位置。 store 封装和管理状态,并且是该状态实际发生变化的唯一地方。当状态发生变化时,它也是发出事件的地方。
商店还负责与后端通信。当状态发生变化并且需要与服务器同步时,商店与后端通信,当它需要内存中没有的数据时,它也会与服务器通信。它有 get(id)
、search(parameters)
等方法。这些方法是针对您的问题的,它们都是 return 承诺,即使状态可以装入内存。这很重要,因为您最终可能会遇到状态不再适合内存,或者无法在内存中过滤或进行高级搜索的用例。通过 return 从您的问题方法中获取承诺,您可以在 return 从内存中获取或询问后端之间切换,而无需更改商店之外的任何内容。
操作数
我的操作非常轻量级,它们对持久化它们封装的突变一无所知。它们只是带有从组件变异到商店的意图。对于较大的应用程序,它们可以包含一些逻辑,但绝不能包含服务器通信之类的东西。
组件
这些是您的 React 组件。他们通过调用商店的问题方法并呈现这些方法的 return 值来与商店交互。他们还订阅商店公开的 change
事件。我喜欢使用 高阶组件 ,这些组件只是包装另一个组件并将道具传递给它。一个例子是:
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>
);
}
});
在此示例中,TodoItemsComponent
是高阶组件,它包装了与商店通信的基本细节。它在获取待办事项时呈现 TodoListComponent
,并在此之前呈现微调器。由于它将待办事项作为 props 传递给 TodoListComponent
,该组件只需要专注于渲染,一旦商店中发生任何变化,它就会重新渲染。并且渲染组件保持完全同步。另一个好处是 TodoItemsComponent
只专注于获取数据并传递它,这使得它对于任何需要待办事项的渲染组件都非常可重用。
高阶分量
术语高阶分量来自术语高阶函数。高阶函数是 return 其他函数的函数。因此,高阶组件是仅包装另一个组件并 return 其输出的组件。
套接字适合Flux单向数据流的什么地方?关于远程数据应从何处进入 Flux 单向数据流,我阅读了两种观点。我看到 Flux 应用程序获取远程数据的方式是在进行服务器端调用时,例如,在随后被解决或拒绝的承诺中。在此过程中可能会触发三种可能的操作:
- 乐观更新视图的初始操作
(FooActions.BAR)
- 解决异步承诺时的成功操作
(FooActions.BAR_SUCCESS)
- 拒绝异步承诺时的错误操作
(FooActions.BAR_ERROR)
商店将侦听操作并更新必要的数据。我已经看到动作创建者和商店本身发出的服务器端调用。我在上述过程中使用了 action creators,但我不确定是否应该对通过 web 套接字获取的数据进行类似处理。我想知道套接字在下图中的位置。
将 Flux 与 WebSockets 或普通的旧 HTTP requests/polling 结合使用的方式确实没有区别。您的商店负责在应用程序状态更改时发出更改事件,如果该更改来自 UI 交互、WebSocket 或创建 HTTP,则从商店外部不应该看到该事件要求。这确实是 Flux 的主要优势之一,因为无论应用程序状态在何处更改,它都会通过相同的代码路径。
一些 Flux 实现倾向于使用 actions/action creators 来获取数据,但我不太同意。
操作是修改应用程序状态的事情。类似于 "the user changed some text and hit save" 或 "the user deleted an item"。将操作想象成数据库的事务日志。如果你丢失了你的数据库,但是你保存并序列化了所有曾经发生的动作,你可以重放所有这些动作并以你丢失的相同 state/database 结束。
所以 "give me item with id X" 和 "give me all the items" 之类的东西不是操作,它们是问题,是关于应用程序状态的问题。在我看来,商店应该通过您在这些商店中公开的方法来回答这些问题。
很想使用 actions/action creators 来获取,因为获取需要异步。通过将异步内容包装在操作中,您的组件和商店可以完全同步。但如果你这样做,你就模糊了动作的定义,而且它还迫使你假设你可以将整个应用程序状态放入内存(因为只有在内存中有答案时你才能同步响应)。
下面是我对 Flux 和不同概念的看法。
商店
这显然是您的应用程序状态所在的位置。 store 封装和管理状态,并且是该状态实际发生变化的唯一地方。当状态发生变化时,它也是发出事件的地方。
商店还负责与后端通信。当状态发生变化并且需要与服务器同步时,商店与后端通信,当它需要内存中没有的数据时,它也会与服务器通信。它有 get(id)
、search(parameters)
等方法。这些方法是针对您的问题的,它们都是 return 承诺,即使状态可以装入内存。这很重要,因为您最终可能会遇到状态不再适合内存,或者无法在内存中过滤或进行高级搜索的用例。通过 return 从您的问题方法中获取承诺,您可以在 return 从内存中获取或询问后端之间切换,而无需更改商店之外的任何内容。
操作数
我的操作非常轻量级,它们对持久化它们封装的突变一无所知。它们只是带有从组件变异到商店的意图。对于较大的应用程序,它们可以包含一些逻辑,但绝不能包含服务器通信之类的东西。
组件
这些是您的 React 组件。他们通过调用商店的问题方法并呈现这些方法的 return 值来与商店交互。他们还订阅商店公开的 change
事件。我喜欢使用 高阶组件 ,这些组件只是包装另一个组件并将道具传递给它。一个例子是:
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>
);
}
});
在此示例中,TodoItemsComponent
是高阶组件,它包装了与商店通信的基本细节。它在获取待办事项时呈现 TodoListComponent
,并在此之前呈现微调器。由于它将待办事项作为 props 传递给 TodoListComponent
,该组件只需要专注于渲染,一旦商店中发生任何变化,它就会重新渲染。并且渲染组件保持完全同步。另一个好处是 TodoItemsComponent
只专注于获取数据并传递它,这使得它对于任何需要待办事项的渲染组件都非常可重用。
高阶分量
术语高阶分量来自术语高阶函数。高阶函数是 return 其他函数的函数。因此,高阶组件是仅包装另一个组件并 return 其输出的组件。