状态由另一个reducer更新后运行reducer

时间:2016-07-27 09:58:58

标签: javascript reactjs redux

让我们说我有一个带有两个缩减器的应用 - tablesfooter合并使用combineReducers()

当我点击某个按钮时,正在调度两个操作 - 一个接一个:"REFRESH_TABLES""REFRESH_FOOTER"

tables reducer正在侦听第一个操作,它会修改表的状态。第二个操作会触发footer减速器。 事情是它需要当前状态的表来做它的事情

我的实现如下所示。

按钮组件:

import React from 'react';

const refreshButton = React.createClass({
    refresh () {
        this.props.refreshTables();
        this.props.refreshFooter(this.props.tables);
    },
    render() {
        return (
            <button onClick={this.refresh}>Refresh</button>
        )
    }
});

export default refreshButton;

ActionCreators:

export function refreshTables() {
    return {
        type: REFRESH_TABLES
    }
}

export function refreshFooter(tables) {
    return {
        type: REFRESH_FOOTER,
        tables
    }
}

问题是道具此时没有更新,因此footer reducer得到的表的状态也没有更新,它包含tables减速器之前的数据格式运行

所以如何从视图中一个接一个地调度多个动作

,从而为减速器获得一个新的状态?

2 个答案:

答案 0 :(得分:1)

似乎您需要处理操作 async,因此您可以使用redux-thuk之类的自定义中间件来执行以下操作:

actions.js

function refreshTables() {
  return {
    type: REFRESH_TABLES
  }
}

function refreshFooter(tables) {
  return {
    type: REFRESH_FOOTER,
    tables
  }
}

export function refresh() {
  return function (dispatch, getState) {
    dispatch(refreshTables())
      .then(() => dispatch(refreshFooter(getState().tables)))
  }
}

组件

const refreshButton = React.createClass({
  refresh () {
    this.props.refresh();
  },
  {/* ... */}
});

答案 1 :(得分:1)

尽管将其异步拆分可能有所帮助,但问题可能在于您使用的是combineReducers。你不应该依赖道具中的表,你想要使用状态的真实来源。

您需要查看重写根减速器,以便可以访问所有状态。我是这样编写的。

const rootReducer = (state, action) => ({ tables: tableReducer(state.tables, action, state), footer: footerReducer(state.footer, action, state) });

有了这个,你现在可以在两个reducer中访问完整状态,所以你不必从道具传递它。

你的减速机可能看起来像这样。

const footerReducer = (state, action, { tables }) => { ... };

这样,当你开始成长并且只能访问你需要的东西时,你实际上并没有拉动状态的所有部分。