我是Redux的新手所以请耐心等待。我想知道以下是否可能和/或最佳,如果是这样,你如何更新reducer中的嵌套对象值?
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!!!****
}
...
}
或者更好的是拥有一条横幅&#39;减速机,&#39; nav&#39;减速机等等?
TIA!
答案 0 :(得分:2)
我对redux也有点新意,所以我不能说'最佳实践'。我会亲自倾向于一个新的reducer,因为你有像SET_BANNER_TEXT
(color,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});
}
答案 1 :(得分:1)
由于您正在更新对象的密钥,请尝试使用此更新密钥
const state = {
...initialState,
banner: {
...initialState.banner, // extend
text: 'newText'
}
}
转换为
var state = _extends({}, initialState, {
banner: _extends({}, initialState.banner, {
text: 'newText'
})
});
ES5中的
检查此jsbin
编辑,如下面的评论中所述,如果上面使用了代码,它将覆盖整个横幅广告对象。您可以使用Object.assign()
在此线程中尝试其他答案并克隆banner
对象。如果您仍想使用传播操作符,我更新了我的答案。
我认为为深度嵌套状态设置特定的reducers也更好。我会写这样的东西
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;
}
}