Redux:如何在状态更改后调度操作

时间:2017-03-22 14:28:09

标签: reactjs redux react-redux

这是一个之前已经讨论过的主题,但我仍然没有找到我喜欢的答案,并且会喜欢一些建议。

我遇到以下问题。我的应用程序包含一个名为CREATE_RESPONSE的操作,该操作会创建一个新的响应记录并将其推送到responses状态。当用户单击按钮时,将从我的组件调度此操作的操作创建者。

onClick={() => {
    this.props.createResponse();
}}

现在,在用户执行此操作后,我想为此新响应打开一个模式。此模式依赖于新的响应状态更改,因此必须在createResponse之后发生。

对我来说最直观的解决方案是使用回调,但我相信这代表了Redux的反模式。

另一种方法是监听响应状态更改,然后在响应数量发生变化时调度操作(类似于订阅示例:http://redux.js.org/docs/api/Store.html#subscribe

function responses(state) {
  return state.responses.size
}

let currentValue
function handleChange() {
  let previousValue = currentValue
  currentValue = responses(store.getState())

  if (previousValue !== currentValue) {
    // Dispatch action here
  }
}

store.subscribe(handleChange)

这里的问题是我们正在响应满足这种条件的所有状态变化。在我的应用中,这在页面加载时被错误地触发。

所以我的问题归结为:为响应状态变化而派遣行动的最佳方式是什么?

修改

以下是我的Modal和Response reducer的简化版本:

模态

const modalState = Immutable.Map({
    isOpen: false,
    view: null,
    modalProps: {}
});

export const modal = (state = modalState, action) => {
    switch (action.type) {
        ...
    }
}

响应

const responseRecord = Immutable.Record({
    id: null,
    ...
});

export const responses = (state = Immutable.List([]), action) => {
    switch (action.type) {
        case 'CREATE_RESPONSE':
            newResponse = new responseRecord(...);

            state = state.unshift(newResponse);

            return state;
        ...

1 个答案:

答案 0 :(得分:1)

您可以在Modal reducer中设置CREATE_RESPONSE个案例。每个动作都会通过每个减速器运行。大多数情况下,它会很快达到默认值。但如果您愿意,可以听取CREATE_RESPONSE并将isOpen设置为true。

虽然我也不认为这是必要的。您可以将isOpen添加到全局状态,而不是newRecord标志。将模态定义为:

<Modal show={this.props.newRecord}...

并清除模态在关闭时调度的任何操作中的newRecord。可能有必要在responses减速器中听取该动作,但这是合法的。

(我有点快速和松散,因为newRecord不是布尔值。它应该可以工作,但你也可以强制它为布尔值{{1} },或直接检查无效)

这应解决在页面加载时打开它的问题。模态完全符合它应该做的事情:只要有新记录就开放,没有任何明确的命令。您只需让React管理其可见性。