更新待办事项 onClick 复选框时出现问题

issue in updating todo onClick checkbox

如果你知道反应(使用上下文api),你可以查看我的问题

这是我的 github 回购:https://github.com/nareshkumar1201/todo-react

我遇到问题,我想 update/toggle 待办事项列表中已完成的 属性 ---

应用程序的当前状态是 - 可以添加待办事项,删除待办事项,现在我正在处理复选框 - 单击复选框时它应该更新待办事项列表中已完成的 属性,问题是当我第一次点击复选框时它工作正常但是如果是 select/uncheck 第二次它不工作......我不知道我哪里错了??

如果有人研究问题会有很大帮助

import React, { Fragment, useContext } from "react";
import PropTypes from "prop-types";
import TodoContext from "../context/TodoContext";

const TodoItem = ({ todo }) => {
  // console.log(todo);

  const todoContext = useContext(TodoContext);
  const { deleteTodo, updateTodo } = todoContext;
  // const { id, todo, completed } = todo;

  **const onChange = (e) => {
    console.log("todoItem: update req", todo.id);
    updateTodo(todo.id);
  };**
  const onClick = () => {
    console.log("todoItem: delete req", todo.id);
    deleteTodo(todo.id);
  };

  return (
    <Fragment>
      <div className="container col-12 todo-item-container">
        <ul className="list-group w-100">
          <li className="list-group-item">
            **<input
              type="checkbox"
              name="todo"
              // value={todo.todo}
              onChange={onChange}
            />**
            <span className="text-info"> {todo.todo}</span>
            <button className="btn float-right ">
              <i
                className="fa fa-pencil-square-o text-info "
                aria-hidden="true"
              ></i>
            </button>
            <button className="btn float-right" onClick={onClick}>
              {" "}
              <i className="fa fa-trash text-info" aria-hidden="true"></i>
            </button>
          </li>
        </ul>
      </div>
    </Fragment>
  );
};

TodoItem.propTypes = {
  todo: PropTypes.object.isRequired,
};

export default TodoItem;

这是状态:

import React, { useReducer } from "react";
import TodoContext from "./TodoContext";
import TodoReducer from "./TodoReducer";
import { v1 as uuid } from "uuid";
import {
  ADD_TODO,
  EDIT_TODO,
  DELETE_TODO,
  DISPLAY_TODOS,
  UPDATE_TODO,
} from "./types";

const TodoState = (props) => {
  const initialState = {
    todos: [
      {
        id: 1,
        todo: "Do cook food",
        completed: false,
      },
      {
        id: 2,
        todo: "Clean Room",
        completed: false,
      },
      {
        id: 3,
        todo: "Wash Car",
        completed: false,
      },
    ],
  };

  const [state, dispatch] = useReducer(TodoReducer, initialState);

  //add todo
  const addTodo = (todo) => {
    todo.id = uuid();
    console.log(todo);
    // todo.completed = false;
    dispatch({ type: ADD_TODO, payload: todo });
  };

  //display todo

  const displayTodos = () => {
    dispatch({ type: DISPLAY_TODOS, payload: state.todos });
  };

  //edit todo

  //delete todo

  const deleteTodo = (id) => {
    console.log("payload id", id);
    dispatch({ type: DELETE_TODO, payload: id });
  };

  //update todo

  **const updateTodo = (id) => {
    console.log("in todoState", id);
    dispatch({ type: UPDATE_TODO, payload: id });
  };**

  return (
    <TodoContext.Provider
      value={{
        todos: state.todos,
        addTodo,
        displayTodos,
        deleteTodo,
        updateTodo,
      }}
    >
      {props.children}
    </TodoContext.Provider>
  );
};

export default TodoState;

这是减速器:

import {
  ADD_TODO,
  EDIT_TODO,
  DELETE_TODO,
  DISPLAY_TODOS,
  UPDATE_TODO,
} from "./types";
// import todoContext from "./TodoContext";

const TodoReducer = (state, action) => {
  switch (action.type) {
    case ADD_TODO:
      return {
        ...state,
        todos: [...state.todos, action.payload],
      };
    case DISPLAY_TODOS:
      return {
        ...state,
        todos: action.payload,
      };
    case DELETE_TODO:
      return {
        ...state,
        todos: state.todos.filter((todoObj) => todoObj.id !== action.payload),
      };
  **case UPDATE_TODO:
      console.log("in reducer :", action.payload);
      return {
        ...state,
        todos: state.todos.map((todoObj) => {
          if (todoObj.id === action.payload) {
            todoObj.completed = !todoObj.completed;
          }
          return todoObj;
        }),
      };**  
    default:
      return state;
  }
};

export default TodoReducer;

屏幕图像:on click on checkbox for the first time -working fine if click on 2nd todo checkbox its not working

您在 UPDATE_TODO 中的 return 有问题。

我已经为你修复了同样的问题,请测试并告诉我。

在对 todos 数组中的对象进行更改时,您需要使用扩展运算符复制它,然后进行更改,然后 return 对象。

        case UPDATE_TODO:
            console.log("in reducer :", action.payload);
            return {
                ...state,
                todos: state.todos.map((todoObj) => {
                    if (todoObj.id === action.payload) {
                        return { ...todoObj, completed: !todoObj.completed };
                    }
                    return todoObj;
                }),
            };