让我们说我有一个带有两个缩减器的应用 - tables
和footer
合并使用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
减速器之前的数据格式运行
所以如何从视图中一个接一个地调度多个动作
,从而为减速器获得一个新的状态?答案 0 :(得分:1)
似乎您需要处理操作 async
,因此您可以使用redux-thuk之类的自定义中间件来执行以下操作:
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 }) => {
...
};
这样,当你开始成长并且只能访问你需要的东西时,你实际上并没有拉动状态的所有部分。