这是我的店铺形状:
export default {
isRequesting: false,
requestError: null,
things: [],
otherThings: []
}
从服务器提取things
和otherThings
时,isRequesting
会发生变化,requestError
可能会被更改。目前,我在reducers/thingReducer.js
和reducers/otherThingReducer.js
之类的缩减器中更改了这些内容,例如:
// reducers/thingReducer.js
import { combineReducers } from 'redux'
import { LOAD_THINGS_REQUESTING, LOAD_THINGS_SUCCESS, LOAD_THINGS_ERROR } from '../actions/actionTypes'
import initialState from './initialState'
export function things(state = initialState.things, action) {
switch(action.type) {
case LOAD_THINGS_SUCCESS:
return action.things
default:
return state
}
}
export function isRequesting(state = initialState.isRequesting, action) {
switch(action.type) {
case LOAD_THINGS_REQUESTING:
return true
case LOAD_THINGS_SUCCESS:
return false
case LOAD_THINGS_ERROR:
return false
default:
return state
}
}
export function requestError(state = initialState.requestError, action) {
switch(action.type) {
case LOAD_THINGS_ERROR:
return action.error
default:
return state
}
}
const thingsReducer = {
things,
isRequesting,
requestError
}
export default thingsReducer
正如您所看到的,我在isRequesting
中有requestError
和thingReducer
的缩减器,我在otherThingReducer
也有同样的东西。
您可能还会看到我导出每个功能,以便我可以在rootReducer.js
const rootReducer = combineReducers({
...thingReducer,
...otherThingReducer
})
export default rootReducer
我从未在示例代码(传播reducers)中看到过这种情况,这让我认为每个reducer文件只应包含一个函数。我知道这是两个问题:
isRequesting
和requestError
是否应该存在于各个reducer文件中(即使它们是全局状态的一部分)
如果是这样的话,它们应该如上所述进行传播和组合。即使1)的答案为否,当每个reducer文件实际需要多个reducer时,我可以使用这种spread / combine方法吗?
答案 0 :(得分:2)
你没有扩散减速器。 thingsReducer
是一个包含reducers的对象,而你正在传播该对象。如果您使用thingsReducer
,可以使combineReducers
成为嵌套的reducer,但我认为没有必要:
const thingsReducer = combineReducers({
things,
isRequesting,
requestError
})
至于您的问题,isRequesting
和requestError
的位置并不重要。通常的做法是将每个reducer放在自己的模块中(例如,查看Ducks https://github.com/erikras/ducks-modular-redux),但这取决于你。您也可以完全删除thingsReducer
并将缩减器直接导入rootReducer.js
,如下所示:
import {things, isRequesting, requestError} from './reducers/thingReducer'
// Or if you decided to put each reducer in its own file
// import things from './reducers/thingsReducer'
// import isRequesting from './reducers/isRequestingReducer'
// ...
const rootReducer = combineReducers({
things,
isRequesting,
requestError,
// do the same for otherThingReducer reducers
})
export default rootReducer
更新: 要在评论中回答您的问题,您可以执行以下操作来简化代码。由于您正在重复使用许多操作,因此可以将reducers合并为如下所示:
export function things(state = initialState, action) {
switch(action.type) {
case LOAD_THINGS_SUCCESS:
return {
...state,
things: action.things,
isRequesting: false
}
case LOAD_THINGS_ERROR:
return {
...state,
requestError: action.error,
isRequesting: false
}
case LOAD_THINGS_REQUESTING:
return {
...state,
isRequesting: true
}
default:
return state
}
}
如果您这样做,则只需将默认things
缩减器导入rootReducer
。
答案 1 :(得分:1)
在缩减器文件的底部,例如things
缩减器,您可以像这样导出一个常量:
export const thing = combineReducers({ things, isRequesting, requestError });
然后在你的root reducer中,你以相同的方式组合它们:
const rootReducer = combineReducers({
thingReducer,
otherThingReducer
})
export default rootReducer
这是一个意见问题,但我更喜欢创建一个适合您的things
,isRequesting
和requestError
的缩减器,如下所示:
// reducers/thingReducer.js
import { combineReducers } from 'redux'
import { LOAD_THINGS_REQUESTING, LOAD_THINGS_SUCCESS, LOAD_THINGS_ERROR } from '../actions/actionTypes'
import initialState from './initialState'
const initialThing = {
data: {},
isLoading: false,
isError: false
}
const things = (
state = initialThing,
action
) => {
switch(action.type) {
case LOAD_THING_REQUESTING:
return {
...state,
isLoading: true
};
case LOAD_THINGS_SUCCESS:
return {
...state,
data: action.things,
isLoading: false,
isError: false
};
case LOAD_THINGS_ERROR:
return {
...state,
isLoading: false,
isError: true
};
default:
return state;
}
}
export default thingsReducer = combineReducers({ things, someOtherReducerFunction });