如何从Redux Store删除元素?filter方法清空数组问题排查
嘿,这种情况我碰到过好几次,大概率是你写filter的判断条件时踩坑了,或者action的参数传递出了问题。咱们一步步来排查:
核心问题:filter的逻辑写反或不匹配
filter是返回符合条件的新数组,删除元素的逻辑应该是保留所有不等于目标ID的元素,如果条件写反或者参数不匹配,就会把所有元素都过滤掉,导致数组清空。
先看正确的DELETE_TODO处理示例
你的reducer里,DELETE_TODO的case应该是这样的:
case DELETE_TODO: return { ...state, todos: state.todos.filter(todo => todo.id !== action.payload.id) };
常见错误点排查
条件写反了
比如你不小心写成了todo.id === action.payload.id,这样filter只会留下要删除的那一个元素;如果这个ID在数组里不存在,就会直接返回空数组,看起来像是整个数组被清空了。Action参数传递错误
你dispatch删除动作时,有没有正确传递要删除的ID?比如如果你的dispatch是:dispatch({ type: DELETE_TODO }) // 没传payload.id那
action.payload.id就是undefined,如果你的条件写反成todo.id === undefined,就会过滤掉所有元素,直接返回空数组。
正确的dispatch应该是:dispatch({ type: DELETE_TODO, payload: { id: 你要删除的ID } })ID类型不匹配
比如你的todo的ID是数字(比如1),但dispatch传的是字符串(比如"1"),如果你的条件是todo.id === action.payload.id,那数字和字符串不相等,filter就会返回空数组。这种情况要确保两边的ID类型一致,要么都转成数字,要么都转成字符串。忘记写default case
如果你的reducer没有default case,当触发了未定义的action类型时,reducer会返回undefined,这也会导致状态异常,看起来像是数组被清空了。一定要加上:default: return state;
调试小技巧
你可以在filter的回调里加个console.log,看看每个todo的ID和action里的ID到底是什么:
todos: state.todos.filter(todo => { console.log('todo.id:', todo.id, 'action.id:', action.payload.id); return todo.id !== action.payload.id; })
这样就能一眼看出是不是参数不匹配或者类型不对了。
完整的reducer参考
给你一个完整的正确示例,你可以对比自己的代码:
import { ADD_TODO, DELETE_TODO } from '../Variables/Variables' const initialState = { todos: [] } // 这里可以直接给state设默认值,不用再判断typeof state === 'undefined' function TodoApp(state = initialState, action) { switch (action.type) { case ADD_TODO: return { ...state, todos: [...state.todos, action.payload.todo] }; case DELETE_TODO: return { ...state, todos: state.todos.filter(todo => todo.id !== action.payload.id) }; default: return state; } } export default TodoApp;
内容的提问来源于stack exchange,提问作者Max Wolfen

