我是 Redux 的新手,所以请耐心等待。我想知道以下情况是否可能和/或最佳,如果是这样,您如何更新化简器中的嵌套对象值?
const initialState = {
banner: {
backgroundColor: 'black',
text: 'Some Title',
textColor: 'white',
image: null
},
nav: {
mainOpen: false,
authOpen: false,
}
...
}
然后在减速器中,这样的东西似乎不起作用......
export default function reducer(state = initialState, action = {}) {
const {type, data} = action;
switch (type) {
case SET_BANNER_TEXT:
return {
...state,
banner.text: data //<-- ****THIS FAILS WITH UNEXPECTED TOKEN!!!****
}
...
}
还是有一个"横幅"减速器、一个"导航"减速器等
更好??啪!
我对 redux 也有点陌生,所以我不能过多地谈论"最佳实践"。 我个人倾向于一个新的化简器,因为你有特定的操作,如SET_BANNER_TEXT
(颜色,img等?)来修改状态树的特定部分,而不是其他。 通过将减速器分开(即使有很多减速器)使它们变得简单,将使事情更容易追踪。
从语法上讲,您可以使用以下内容实现您尝试做的事情:
export default function reducer(state = initialState, action = {}) {
const {type, data} = action;
switch (type) {
case SET_BANNER_TEXT:
const newBannerState = Object.assign({}, state.banner, {text: data});
return Object.assign({}, state, {banner: newBannerState});
}
由于您要更新对象的键,请尝试使用它来更新键
const state = {
...initialState,
banner: {
...initialState.banner, // extend
text: 'newText'
}
}
翻译为
var state = _extends({}, initialState, {
banner: _extends({}, initialState.banner, {
text: 'newText'
})
});
在 ES5 中
检查此JSBINb
编辑:如下面的注释中所述,如果使用上面的代码,它将覆盖整个横幅对象。您可以使用Object.assign()
尝试此线程中的其他答案并克隆banner
对象。如果您仍然想使用点差运算符,我更新了我的答案。
我认为最好为深度嵌套状态使用特定的化简器。我会写成这样
export function rootReducer(state = initialState, action) {
switch (action.type) {
case SET_BANNER_TEXT:
case SET_BANNER_BG:
return Object.assign({}, state,
{
banner: bannerReducer(state.banner, action)
}
);
// ...
default:
return state;
}
}
function bannerReducer(state, action) {
switch (action.type) {
case SET_BANNER_TEXT:
return Object.assign({}, state, {text: action.payload});
case SET_BANNER_BG:
return Object.assign({}, state, {backgroundColor: action.payload});
// ...
default:
return state;
}
}