【发布时间】:2016-04-02 12:40:57
【问题描述】:
我知道 Redux 是对 Flux 更好的“实现”,或者说它是为了简化事物(应用程序状态管理)而进行的重新设计。
我听说过很多关于响应式编程 (RxJS) 的知识,但我还没有深入学习它。
所以我的问题是:这两种技术之间是否有任何交集(任何共同点)或者它们是互补的? ...还是完全不同?
【问题讨论】:
标签: javascript rxjs redux
我知道 Redux 是对 Flux 更好的“实现”,或者说它是为了简化事物(应用程序状态管理)而进行的重新设计。
我听说过很多关于响应式编程 (RxJS) 的知识,但我还没有深入学习它。
所以我的问题是:这两种技术之间是否有任何交集(任何共同点)或者它们是互补的? ...还是完全不同?
【问题讨论】:
标签: javascript rxjs redux
简而言之,它们是非常不同的库,用途非常不同,但确实有一些模糊的相似之处。
Redux 是一个用于管理整个应用程序状态的工具。它通常用作 UI 的架构。将其视为(一半)Angular 的替代品。
RxJS 是一个反应式编程库。它通常用作在 JavaScript 中完成异步任务的工具。将其视为 Promises 的替代方案。
反应式编程是一种范式(工作和思维方式),其中远距离观察数据变化。数据不会远距离改变。
这是一个从远处改变的例子:
// In the controller.js file
model.set('name', 'George');
Model 已从 Controller 更改。
这是一个远距离观察的例子:
// logger.js
store.subscribe(function (data) {
console.log(data);
});
在 Logger 中,我们(远距离)观察 Store 中发生的数据变化,并写入控制台。
Redux 稍微使用了响应式范式:Store 是响应式的。您不会从远处设置其内容。这就是 Redux 中没有 store.set() 的原因。商店从远处观察动作,并改变自己。 Store 允许其他人从远处观察它的数据。
RxJS 也使用 Reactive 范式,但它不是一种架构,而是为您提供基本的构建块,Observables,以完成这种“远距离观察”模式。
总之,为了不同的目的,非常不同的事情,但分享一些想法。
【讨论】:
它们是非常不同的东西。
RxJS 可用于响应式编程,是一个非常全面的库,包含 250 多个运算符。
Redux 就像 github 存储库“Redux 是 JavaScript 应用程序的可预测状态容器”中所述。
Redux 只是一个处理应用程序状态的工具。但相比之下,你可以只用 RxJS 构建一个完整的应用程序。
希望这会有所帮助:)
【讨论】:
Redux 只是一个状态管理库,带有定义明确的更新操作标准。只要您坚持标准,您就可以使您的数据流保持健全且易于推理。它还带来了通过中间件和存储增强器增强数据流的能力。
RxJS 是用于反应式编程的工具包。实际上,您可以将应用程序中发生的每一件事都视为一个流。 RxJS 提供了一个非常丰富的工具集来管理这些流。
RxJS 和 Redux 在哪里拦截?在 redux 中,您使用操作更新您的状态,显然这些操作可以被视为流。使用像 redux-observable 这样的中间件(您不必这样做),您可以以反应方式实现所谓的“业务逻辑”。另一件事是你可以从你的 redux 存储中创建一个 observable,这有时可能比使用增强器更容易。
【讨论】:
简而言之:
Redux: 受 Flux 启发的库,用于状态管理。
RxJS:它是另一个基于响应式编程哲学的 Javascript 库,用于处理“流”(Observables 等)[阅读响应式编程以了解流概念]。
【讨论】:
我只是想添加一些与我在使用 Redux 启发的 RxJS 代码时的实际差异。
我将每个动作类型映射到一个主题实例。
每个有状态的组件都会有一个 Subject ,然后将其映射到 reducer 函数中。
所有 reducer 流与merge 组合,然后scan 输出状态。
默认值是在scan 之前使用startWith 设置的。我使用publishReplay(1) 表示状态,但以后可能会删除它。
react pure render 函数将仅用于通过发送所有生产者/主题来生成事件数据的地方。
如果您有子组件,您需要描述这些状态是如何组合到您的。 combineLatest 可能是一个很好的起点。
在实现上的显着差异:
没有中间件,只有 rxjs 操作符。我认为这是最大的力量和弱点。你仍然可以借用概念,但我发现很难从 redux 和 cycle.js 等姐妹社区获得帮助,因为它是另一种自定义解决方案。这就是为什么我需要在本文中写“我”而不是“我们”。
没有用于操作类型的开关/大小写或字符串。您有一种更动态的方式来分离动作。
rxjs 可以在别处用作工具,不包含在状态管理中。
生产者数量少于操作类型(?)。我不确定这一点,但是您可以在监听子组件的父组件中做出许多反应。这意味着更少的命令式代码和更少的复杂性。
您拥有解决方案。不需要框架。好和坏。无论如何,您最终都会编写自己的框架。
它更加分形,您可以轻松订阅来自子树或应用状态树多个部分的更改。
我还致力于将子组件描述为流的更大好处。这意味着我们不必在 reducer 中完成父子状态,因为我们可以(“只是”)基于组件结构递归地组合状态。
我还考虑跳过 react 并使用 snabbdom 或其他方法,直到 React 更好地处理响应状态。为什么我们应该向上构建我们的状态只是为了再次通过道具分解它?所以我会尝试用 Snabbdom 制作这个模式的第 2 版。
这是一个更高级但更小的 sn-p,state.ts 文件在其中构建状态流。这是 ajax-form 组件的状态,它获取具有验证规则和 css 样式的字段(输入)对象。在这个文件中,我们只是使用字段名称(对象键)将所有子状态组合成表单状态。
export default function create({
Observable,
ajaxInputs
}) {
const fieldStreams = Object.keys(ajaxInputs)
.map(function onMap(fieldName) {
return ajaxInputs[fieldName].state.stream
.map(function onMap(stateData) {
return {stateData, fieldName}
})
})
const stateStream = Observable.combineLatest(...fieldStreams)
.map(function onMap(fieldStreamDataArray) {
return fieldStreamDataArray.reduce(function onReduce(acc, fieldStreamData) {
acc[fieldStreamData.fieldName] = fieldStreamData.stateData
return acc
}, {})
})
return {
stream: stateStream
}
}
虽然代码可能不会单独说明太多,但它显示了如何向上构建状态,以及如何轻松生成动态事件。付出的代价是你需要理解不同风格的代码。我愿意为此付出代价。
【讨论】: