数组中的对象在使用特定的reducer/action后会变成未定义的



我正在使用一个经典的待办事项列表项目来学习Redux,但我遇到了一个奇怪的问题。

基本上,我有一个带有复选框的待办事项列表,当用户单击复选框时,会调度一个操作,该操作应该将该对象的已完成属性标记为true,并且组件应该更新。

然而。。。当此操作启动时,本应标记为完成的对象成功返回其所有属性,但待办事项列表的其余部分(数组中的其他对象)已损坏,丢失了所有属性,并变为"未定义",从而导致渲染出现问题。

我试图包含所有我认为相关的代码,但我认为我的reducer中有错误,但我找不到似乎找到了问题。

Todo List组件

class TodoList extends Component {
render(){
const {todos, showCompleted, searchTerm} = this.props;
const renderTodos = () => {
if (todos.length === 0) {
return (
<p className="container__message">Nothing to do.</p>
);
}
return TodoAPI.filterTodos(todos, showCompleted, searchTerm).map((todo) => {
return (
<Todo key={todo.id} {...todo}/>
);
});
};
return (
<div>
{renderTodos()}
</div>
);
}
}
export default connect((state) => {
return state;
})(TodoList);

Todo组件

class Todo extends Component {
render() {
const {id, text, completed, createdAt, completedAt, dispatch} = this.props;
const todoClass = completed
? 'todo todo-completed'
: 'todo';
const renderDate = () => {
let displayMessage = 'Created ';
let timestamp = createdAt;
if (completed) {
displayMessage = 'Completed ';
timestamp = completedAt;
}
return displayMessage + moment.unix(timestamp).format('MMM Do YYYY @ h:mm a');
};
return (
<div className={todoClass}
onClick={event => dispatch(actions.toggleTodo(id)) }>
<input type="checkbox" checked={completed} readOnly/>
<div>
<p>{text}</p>
<p className="todo__subtext">{renderDate()}</p>
</div>
</div>
);
}
}
export default connect()(Todo);

操作

export const toggleTodo = (id) => {
return {
type: 'TOGGLE_TODO',
id: id
};
};

减速器

export const todosReducer = (state = [], action) => {
switch (action.type) {
case 'TOGGLE_TODO':
return state.map((todo) => {
if (todo.id === action.id) {
let nextCompleted = !todo.completed;
return {
...todo,
completed: nextCompleted,
completedAt: todo.completed ? moment().unix() : 0
};
}
});
default:
return state;
}
};

问题是,如果condition todo.id === action.id失败,您就不是returning。有了map,如果你什么都不return,默认情况下它会是returnundefined,试试这个:

return state.map((todo) => {
if (todo.id === action.id) {
let nextCompleted = !todo.completed;
return {
...todo,
completed: nextCompleted,
completedAt: todo.completed ? moment().unix() : 0
};
}else{
return todo;
}
});

检查此项:

a=[1,2,3,4,5,6];
b = a.map ( i => { if(i % 2 == 0) return i;})
console.log(b);

最新更新