我正在使用 react
和 redux
创建一个待办事项列表,当我更新 redux 状态数组时,它不会重新渲染,我的状态实际上是一个包含对象的数组,像这样:
[{index:1,value:'item1',done:false}, {index:2,value:'item2',done:false}]
我想要做的是点击时我想将done的值切换为“true”, 但不知何故我无法做到这一点。
这就是我在 reducer 中所做的:
list.map((item)=>{
if(item.index===index){
item.done=!item.done;
return [...state,list]
}
但即使单击切换按钮时完成不断变化,它也不会重新渲染。
似乎我正在以某种方式改变状态。 请告诉我哪里出了问题以及我应该做什么。
您能举出类似的例子吗?我可以正确更新简单数组的状态,但是对包含对象的数组执行此操作,这让我感到困惑。 那么,您能举个例子吗?
这是完整的 reducer 代码:
export default function todoApp(state=[],action){
switch(action.type){
case 'ADD_TODO':
return [...state,action.item];
case 'TOGGLE_TODOS':
const index = action.index;
const list = state;
list.map((item)=>{
if(item.index===index){
item.done=!item.done;
}
return [...state,list];
});
default:
return state;
}
}
最佳答案
It seems that somehow I am mutating the state.
正确的是,你正在改变状态,因为在js中,变量总是获取对象/数组的引用。在您的情况下,item
将拥有数组中每个对象的引用,并且您将直接改变 item.done
的值。
另一个问题是您没有正确返回最终对象,并且您还需要为每个 map 迭代返回值,否则默认情况下它将返回undefined
。
这样写:
case "TOGGLE_TODOS":
return list.map((item) => (
item.index===index? {...item, done: !item.done}: item
))
或者:
case 'TOGGLE_TODOS':
const index = action.index;
const newState = [ ...state ];
newState[index] = { ...state[index], done: !newState[index].done };
return newState;
完整代码:
export default function todoApp(state=[], action){
switch(action.type){
case 'ADD_TODO':
return [...state, action.item];
case 'TOGGLE_TODOS':
const index = action.index;
return state.map((item) => (
item.index===index? {...item, done: !item.done}: item
))
default:
return state;
}
}
检查此片段:
let list = [
{done:true, index:0},
{done:false, index:1},
{done: true, index:2}
]
let index = 1;
let newList = list.map(item => (
item.index===index? {...item, done: !item.done}: item
))
console.log('newList = ', newList);
关于reactjs - 如何在redux中更新数组内的单个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49012900/