减速器影响远处状态的正确方法是什么?

时间:2018-09-22 01:52:10

标签: javascript redux

我正在构建一个React-Redux项目,并且试图习惯于Redux的使用,并避免以使以后难以维护代码的方式将它们混在一起。我也是这个生态系统的新手。

我有一个看起来像这样的嵌套状态:

{ foo: {stuff}, bar: {baz: {stuff} } }

,我使用combineReducers,所以foobarbaz都有自己的化简词来解释有关更改其自身状态的相关动作。但是我遇到了这样一种情况,根据baz的状态,某个动作可能会暗示foo可能会感兴趣。

我基本上有三个想法,我讨厌第一个,不知道如何做另外两个:

1)使bar / baz的异径管可以进入整个状态,并要求他们对此负责。

这使这种确切的情况易于处理,但是从关注点分离的角度来看,这似乎很糟糕。

2)baz减速器以某种方式调度了foo随后将采取的相关操作。

从描述性的角度来看,这对我来说很有意义,但是我实际上并不知道该怎么做。它不明显的事实使我认为Redux与此相反。

3)导入一些简单的魔术库

不过,我不知道哪个图书馆会这样做。似乎这不是redux-thunk所做的(尽管我不确定),然后我真的不知道。

2 个答案:

答案 0 :(得分:0)

我建议您使减速器保持简单。他们在那里可以修改他们关心的状态部分,而没有其他任何事情。

如果一个“动作”影响多个片段,那么它应该分派多个“动作”。在这一点上,命名可能会引起混乱,但是基本上const wrapper = mount(<MyComponent {...props} />); expect(wrapper.find('#input-element').first().getDOMNode().indeterminate).toBeTruthy(); // SUCCESS 允许您这样做。

如果您有常规的动作创建者,例如redux-thunkmodifyFoo,它们仅返回分配给减速器的动作对象,并且启用了modifyBar,则可以创建更复杂的“动作”分派两者。例如。

redux-thunk

使用function modifyFoo(options) { return { type: "MODIFY_FOO", payload: options }}; } function modifyBar(options) { return { type: "MODIFY_BAR", payload: options }}; } function modifyFooBar(options) { return (dispatch, getState) => { const appState = getState(); dispatch(modifyFoo(options.foo, appState.baz)); dispatch(modifyBar(options.bar)); } } 可以访问应用程序的完整状态。

答案 1 :(得分:0)

tl; dr-我决定使用redux-loop,它可以让您描述减速器的副作用,而无需使减速器为纯/无状态。

为什么我没有为此使用redux-thunk

@lecstor的回答中表示的最常见方法(基于我的谷歌搜索)是​​使用redux-thunk。在典型的redux-thunk代码组织中,您必须先弄清楚将要发生的所有事情,然后再通过thunk调度一些动作,异步操作等。

在这种情况下,不利的一面是第二个动作是(a)以第一个动作触发后的状态为条件,并且(b)不能从状态本身派生,而必须从我们在此操作之后的 状态。

因此,对于redux-thunk,您要么必须复制化简器的逻辑(坏),要么在化简器之前进行所有业务逻辑,然后启动一堆描述状态变化的动作。

这就是说,redux-thunk在简化程序发生之前先完成了它的魔力。

为什么我认为redux-loop更合适:

另一方面,redux-loop会在化简器发生后 神奇,从而使化简器能够描述这些效果(包括启动异步操作,调度进一步的操作等)而不会中断无国籍。

对于历史记录,这意味着您可以在上面的foo减速器中进行以下操作:

// ... nextState is the new fooState
if (isWeird(nextState)) {
  return loop(nextState, Cmd.action(makeWeirdAction()));
} else {
  return nextState;
}

以便所有其他化简者可以按自己的意愿解释或忽略奇怪的动作,而不是在动作创建者中一次做出所有这些决定。