我有2个减速器A,B分别位于包A和B中。我在A套餐中加入了两种减速机。
包A使用包B.但是,包B有一个form
,在提交时必须更新包A中定义的组件。我已经在包B中定义了一个动作,并希望减速器A处理行动。
我能够查看动作的case语句,但reducer A中的状态并不反映全局状态。我想过,一旦商店的州更新了所有减速器状态'组成商店的内容会更新,但似乎并非如此。 Reducer A维护自己的状态,该状态是全局存储状态的子集。如何使减速机A访问减速机B带来的状态更新?
我有一个想法是在A中合并减速器B,但这会使包B依赖于A.我还没有尝试使用redux-form
因为我们自己的内部组件用于表单元素。还有其他想法/建议吗?
更新:添加一些代码,动作类型是定义为字符串的常量。提交表单后,我希望调度SUBMIT_COURSE_DATA
操作并在reducer A中更新状态。存储主要使用combineReducers
来组合减速器A和B.
// Reducer B
const bReducer = (state = {
selectedCourse: {
courseType: ""
},
}, action) => {
const newState = Object.assign({}, state);
switch (action.type) {
case COURSE_DATA_CHANGE:
newState.selectedCourse.courseType = action.courseType;
}
};
export default bReducer;
// Action B
export function handleCourseDataChange(courseType) {
return {
type: COURSE_DATA_CHANGE,
courseType : courseType
}
}
export function submitCourseData() {
return {
type: SUBMIT_COURSE_DATA,
}
}
//Reducer A
const formReducers = (state = {
coursesContext: {
data: [],
actions: []
},
}, action) => {
const newState = Object.assign({}, state);
case SUBMIT_COURSE_DATA:
newState.coursesContext.data = [newState.coursesContext.data, Object.assign({},
{"Course_Type": newState.selectedCourse.courseType})];
return newState;
// store.js
import { reducers as modalManagerReducers } from 'modal';
import { createStore, combineReducers, applyMiddleware } from 'redux';
import reduceReducers from 'reduce-reducers';
import createSagaMiddleware from 'redux-saga';
import { baseReducers } from '../../../packageB/src/components/AddCourseDialog';
import courseFormReducers from './reducers';
import formSubmissionReducer from './formReducer';
import { SUBMIT_COURSE_DATA } from '../../../packageB/src/components/actions';
const sagaMiddleware = createSagaMiddleware();
const courseReducer = Object.assign({}, { model: courseFormReducers });
const mainReducer = combineReducers(Object.assign({}, baseReducers, courseReducer, modalManagerReducers ));
const formSubmissionReducer = function(state,action) {
switch (action.type)
{
case SUBMIT_COURSE_DATA:
return formSubmissionReducer(state.selectedCourse);
default:
return state;
}
};
const rootReducer = reduceReducers(mainReducer, formSubmissionReducer);
const store = createStore(
rootReducer,
compose(applyMiddleware(sagaMiddleware)),
);
export {store, sagaMiddleware};
// formSubmissionReducer is same as reducer A. Just that now reducer A
doesn't have a case for SUBMIT_COURSE_DATA anymore.
//AddCourseDialog
// Form Submit handler
handleSubmit(e) {
e.preventDefault();
this.props.dispatch(submitCourseData());
}
// How to ensure that formSubmissionReducer in the store gets invoked here?
const baseReducers = Object.assign({}, { baseReducer: courseBaseReducers });
export { baseReducers };
export default connect(mapStateToProps)(AddCourseDialog);
已更新以包含AddCourseDialog
容器,该容器处理更改并通过调度操作提交事件。
答案 0 :(得分:1)
根据Redux FAQ entry on sharing state between slice reducers:
许多用户后来想尝试在两个Reducer之间共享数据,但发现
combineReducers
不允许他们这样做。有几种方法可以使用:
- 如果reducer需要知道来自另一个状态片的数据,则可能需要重新组织状态树形状,以便单个reducer处理更多数据。
- 您可能需要编写一些自定义函数来处理其中一些操作。这可能需要使用您自己的顶级reducer函数替换
combineReducers
。您还可以使用reduce-reducers等实用程序来运行combineReducers
来处理大多数操作,还可以为跨越状态切片的特定操作运行更专业的reducer。- 异步动作创建者(如redux-thunk)可以通过
getState()
访问整个州。操作创建者可以从状态中检索其他数据并将其放入操作中,以便每个reducer都有足够的信息来更新自己的状态切片。
还有many other third-party reducer utilities available,其中一些可能有用。特别是,您可能希望查看ryo33/combine-section-reducers,convoyinc/combined-reduction和KodersLab/topologically-combine-reducers。
更新
根据你的问题,为什么" r
不是减速机",现在你有:
const courseReducer = Object.assign({}, { model: courseFormReducers });
const mainReducer = Object.assign({}, baseReducers, courseReducer,
modalManagerReducers );
那不你需要什么。您需要将这些切片缩减器传递给combineReducers
以形成初始"每切片处理"减速器。然后,如果您确实想使用reduceReducers
,请通过"顶级状态"减速机。以下是一个例子:
const combinedReducer = combineReducers({
model : courseFormReducers,
anotherSlice : anotherSliceReducer
});
const rootReducer = reduceReducers(combinedReducer, formSubmissionReducer);
const store = createStore(rootReducer);