在 Redux 中改变状态
Changing state in Redux
我正在尝试向 state
中的数组添加一个元素并更改另一个数组元素的 属性。假设我们有以下 state
结构:
{
menuItems: [{
href: '/',
active: true
}]
}
发送 ADD_MENU_ITEM
操作后,我想以这个 state
:
结束
{
menuItems: [{
href: '/new',
active: true
}, {
href: '/',
active: false,
}]
}
我已经尝试在 Redux reducers 中以多种方式管理它:
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;
}
}
}
在第四次尝试中,我使用的是 React 的 Immutability Helpers,但它从未奏效。我在返回状态之前将状态记录到控制台并且它正确记录,但是当在重新 rendered
的组件中登录时,menuItems 数组不添加第一个项目,尽管 active
成员设置为 false
.
我可能做错了什么?
reducer 中的状态应该是不可变的,因此不应修改。还建议尽可能展平您的对象。
在您的场景中,您的初始状态可以是这样的数组:
[{
href: '/',
active: true
}]
在你的 reducer 中,尝试返回一个全新的数组,如下所示:
function reducer(state = {}, action) {
switch (action.type) {
case ADD_MENU_ITEM: {
return [
action.newMenuItem,
...state.map(item => Object.assign({}, item, { active: false }))
];
}
}
}
可以在此处找到有关减速器的更多信息:Redux Reducers Documentation
文档中的有用摘录:
It’s very important that the reducer stays pure. Things you should never do inside a reducer:
- Mutate its arguments;
- Perform side effects like API calls and routing transitions;
- Calling non-pure functions, e.g. Date.now() or Math.random().
添加了更多信息
在你的减速器中,对于所有四次尝试,你在返回之前修改现有状态。
这会导致 react-redux
,在检查您的状态是否已更改时,看不到任何更改,因为前一个状态和下一个状态都指向同一个对象。
我指的是以下几行:
第一次尝试:
// This line modifies the existing state.
state = Object.assign({}, state, { menuItems: menuItems });
第二次尝试:
// This line modifies the existing state.
state = Object.assign({}, state, {menuItems: Object.assign([], menuItems)});
第三次尝试:
// This line modifies the existing state.
state = (Object.assign({}, state, {
menuItems: [
Object.assign({}, newMenuItem),
...menuItems
]
}));
第四次尝试:
// This line modifies the existing state.
state = update(state, {
menuItems: {$unshift: new Array(newMenuItem)}
});
我正在尝试向 state
中的数组添加一个元素并更改另一个数组元素的 属性。假设我们有以下 state
结构:
{
menuItems: [{
href: '/',
active: true
}]
}
发送 ADD_MENU_ITEM
操作后,我想以这个 state
:
{
menuItems: [{
href: '/new',
active: true
}, {
href: '/',
active: false,
}]
}
我已经尝试在 Redux reducers 中以多种方式管理它:
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;
}
}
}
在第四次尝试中,我使用的是 React 的 Immutability Helpers,但它从未奏效。我在返回状态之前将状态记录到控制台并且它正确记录,但是当在重新 rendered
的组件中登录时,menuItems 数组不添加第一个项目,尽管 active
成员设置为 false
.
我可能做错了什么?
reducer 中的状态应该是不可变的,因此不应修改。还建议尽可能展平您的对象。
在您的场景中,您的初始状态可以是这样的数组:
[{
href: '/',
active: true
}]
在你的 reducer 中,尝试返回一个全新的数组,如下所示:
function reducer(state = {}, action) {
switch (action.type) {
case ADD_MENU_ITEM: {
return [
action.newMenuItem,
...state.map(item => Object.assign({}, item, { active: false }))
];
}
}
}
可以在此处找到有关减速器的更多信息:Redux Reducers Documentation
文档中的有用摘录:
It’s very important that the reducer stays pure. Things you should never do inside a reducer:
- Mutate its arguments;
- Perform side effects like API calls and routing transitions;
- Calling non-pure functions, e.g. Date.now() or Math.random().
添加了更多信息
在你的减速器中,对于所有四次尝试,你在返回之前修改现有状态。
这会导致 react-redux
,在检查您的状态是否已更改时,看不到任何更改,因为前一个状态和下一个状态都指向同一个对象。
我指的是以下几行:
第一次尝试:
// This line modifies the existing state.
state = Object.assign({}, state, { menuItems: menuItems });
第二次尝试:
// This line modifies the existing state.
state = Object.assign({}, state, {menuItems: Object.assign([], menuItems)});
第三次尝试:
// This line modifies the existing state.
state = (Object.assign({}, state, {
menuItems: [
Object.assign({}, newMenuItem),
...menuItems
]
}));
第四次尝试:
// This line modifies the existing state.
state = update(state, {
menuItems: {$unshift: new Array(newMenuItem)}
});