复选框需要点击两次才能做出反应

checkbox needing two click to react

我正在尝试制作待办事项应用程序。我在每个项目上都有复选框,当我单击我的复选框时,我试图将 checked(iscompleted) 的值更改为 true,但它需要单击两次才能做到这一点,为什么会发生这种情况,我试图解决这个问题很长时间现在时间

import React from "react";
import { useState, useEffect } from "react";
import { ControlPanel } from "./ControlPanel";

export const Input = () => {
  const [todos, setTodos] = useState([]);
  const [newTodo, setNewTodo] = useState("");
  const [isCompleted, setIsCompleted] = useState(false);

  const handleChange = (e) => {
    setNewTodo(e.target.value);
  };

  const handleSubmit = (e) => {
    e.preventDefault();

    const adding = {
      task: newTodo,
      id: Math.floor(Math.random() * 100000),
      checked: isCompleted
    };
    if (newTodo.length) {
      setTodos(todos.concat(adding));
      setNewTodo("");
    }
  };
  const checkbox = (index) => {
    const check = [...todos];
    check[index].checked = isCompleted
    setIsCompleted(!isCompleted);

    setTodos(check);
    console.log(todos);
  
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input
          type="text"
          value={newTodo}
          onChange={handleChange}
          placeholder="what needs to be done?"
        />

        <ul>
          {todos &&
            todos.map((todo, index) => {
              return (
                <div>
                  <input
                  
                    checked={todo.checked ? true : false}
                    type="checkbox"
                    onChange={() => checkbox(index)}
                  />
                  <li key={todo.index}>{todo.task}</li>
                </div>
              );
            })}
        </ul>
        <ControlPanel todos={todos} />
      </form>
    </div>
  );
};

您的主要问题在于此行:

check[index].checked = isCompleted

isCompleted 是一个 component-level 状态,而不是 Todo 状态。由于您想 切换 基于 Todo 项目本身的复选框的值,您应该执行如下操作:

check[index].checked = !check[index].checked

顺便说一句,在这段代码中:

todos.map((todo, index) => {
  return (
    <div>
      <input
        checked={todo.checked ? true : false}
        type="checkbox"
        onChange={() => checkbox(index)}
      />
      <li key={todo.index}>{todo.task}</li>
    </div>
  );
})

key 道具不在正确的位置。它应该是父元素——在本例中是 <div> 元素:

todos.map((todo, index) => {
  return (
    <div key={index}>
      <input
        checked={todo.checked ? true : false}
        type="checkbox"
        onChange={() => checkbox(index)}
      />
      <li>{todo.task}</li>
    </div>
  );
})