使用特定的reducer / action后,数组中的对象变为未定义

时间:2017-02-06 19:02:08

标签: reactjs redux

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

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

然而......当这个动作触发时,应该被标记为完成的对象成功返回其所有属性,但其余的待办事项列表(数组中的其他对象)被破坏,失去了所有属性,它们变成'undefined',从而导致渲染中出现问题。

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

Todo列表组件

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;
    }
};

1 个答案:

答案 0 :(得分:2)

如果returning失败,问题是你不是condition todo.id === action.id。使用map如果您没有return任何内容,默认情况下会return undefined,请尝试以下操作:

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);