我试图在一个数组中添加一个元素state
并更改另一个数组元素的属性.假设我们有以下state
结构:
{
menuItems: [{
href: '/',
active: true
}]
}
Run Code Online (Sandbox Code Playgroud)
在调度ADD_MENU_ITEM
动作之后,我想最终得到这个state
:
{
menuItems: [{
href: '/new',
active: true
}, {
href: '/',
active: false,
}]
}
Run Code Online (Sandbox Code Playgroud)
我尝试过几种方式在Redux Reducer中管理它:
function reducer(state = {}, action) {
switch (action.type) {
case ADD_MENU_ITEM: {
let menuItems = state.menuItems;
let newMenuItem = action.newMenuItem;
// First try
menuItems[0].active = false;
menuItems.unshift(newMenuItem);
state = Object.assign({}, state, { menuItems: menuItems });
// Second try
menuItems[0].active = false;
menuItems.unshift(newMenuItem);
state = Object.assign({}, state, {menuItems: Object.assign([], menuItems)});
// Third try
menuItems[0].active = false;
state = (Object.assign({}, state, {
menuItems: [
Object.assign({}, newMenuItem),
...menuItems
]
}));
// Fourth try
menuItems[0].active = false;
state = update(state, {
menuItems: {$unshift: new Array(newMenuItem)}
});
console.log(state);
return state;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在第四次尝试中,我使用的是React的Immutability Helpers,但它永远不会奏效.我登录的状态到控制台返回前的状态并正确记录,但得到重新的组件内登录时rendered
,该阵列的MenuItems不添加的第一个项目,虽然active
成员设置为false
.
我能做错什么?
reducer中的状态应该是不可变的,因此不应该修改.还建议尽可能展平您的物体.
在您的场景中,您的初始状态可能是一个数组:
[{
href: '/',
active: true
}]
Run Code Online (Sandbox Code Playgroud)
在您的reducer中,尝试返回一个全新的数组,如下所示:
function reducer(state = {}, action) {
switch (action.type) {
case ADD_MENU_ITEM: {
return [
action.newMenuItem,
...state.map(item => Object.assign({}, item, { active: false }))
];
}
}
}
Run Code Online (Sandbox Code Playgroud)
有关Reducer的更多信息,请访问:Redux Reducers文档
文档的有用摘录:
减速机保持纯净非常重要.你应该在减速机内做的事情:
- 改变其论点;
- 执行API调用和路由转换等副作用;
- 调用非纯函数,例如Date.now()或Math.random().
更多信息已添加
在您的reducer和所有四次尝试中,您在返回之前修改现有状态.
这会导致在react-redux
检查您的状态是否已更改时,不会看到任何更改,因为前一个和下一个状态都指向同一个对象.
以下是我所指的行:
第一次尝试:
// This line modifies the existing state.
state = Object.assign({}, state, { menuItems: menuItems });
Run Code Online (Sandbox Code Playgroud)
第二次尝试:
// This line modifies the existing state.
state = Object.assign({}, state, {menuItems: Object.assign([], menuItems)});
Run Code Online (Sandbox Code Playgroud)
第三次尝试:
// This line modifies the existing state.
state = (Object.assign({}, state, {
menuItems: [
Object.assign({}, newMenuItem),
...menuItems
]
}));
Run Code Online (Sandbox Code Playgroud)
第四次尝试:
// This line modifies the existing state.
state = update(state, {
menuItems: {$unshift: new Array(newMenuItem)}
});
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
9312 次 |
最近记录: |