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

问题描述

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

这是我的github存储库:https://github.com/nareshkumar1201/todo-react

我面临问题,我想更新/切换待办事项列表中的完成属性---

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

如果有人对此问题进行调查,将会有很大的帮助

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",{
        id: 3,todo: "Wash Car",],};

  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,} 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中的退货存在问题。

我已为您修复了该问题,请进行测试并告诉我。

在todos数组中更改对象时,您需要使用散布运算符将其复制,然后进行更改然后返回对象。

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