这是我的组件:

enter image description here

单击"删除"后,它下面的复选框变为选中状态,即使从未单击过它.

enter image description here

下面是父组件和子组件实现(新的react )

任务列表.js公司

import { useState, useRef } from "react";
import Task from "./Task";
function TaskList({ className, tasks, setTasks }) {
  let inputRef = useRef();

  return (
    <div className={className}>
      <ul className="grow overflow-y-scroll">
        {tasks.map((task, i) => (
          <Task
            description={task.description}
            onChange={() => {
              task.checked = !task.checked;
            }}
          />
        ))}
      </ul>
      <input
        className="my-2 border-b-2 border-blue-300"
        placeholder="Enter task description..."
        ref={inputRef}
      ></input>
      <button
        className="rounded-md bg-blue-400 w-full p-4 text-white text-2xl"
        onClick={() => {
          setTasks([
            ...tasks,
            { description: inputRef.current.value, checked: false },
          ]);
        }}
      >
        Add
      </button>
      <button
        className="w-full bg-red-600 rounded-md p-2"
        onClick={() => {
          setTasks(tasks.filter((t) => !t.checked));
        }}
      >
        Delete
      </button>
    </div>
  );
}

export default TaskList;

任务js公司

import React, { useState } from "react";

function Task({ description, onChange }) {
  return (
    <li className="flex flex-row my-2">
      <input className="mx-2" type="checkbox" onChange={onChange}></input>
      <span>{description}</span>
    </li>
  );
}

推荐答案

您缺少任务组件中的键,并且使用的是不受控制的组件,因此在重新渲染时,您没有充分说明DOM中存在的哪个元素对应于哪个<Task>.最好的解决方法是:

  • 使用受控部件,而不是非受控部件;组件通常更具可预测性,并且可用于状态,因为视图应该来自状态.(如果使用受控组件,也可以避免求助于ref).可以控制文本输入和复选框.
  • .map返回时使用键
  • 不要在React中改变状态;task.checked = !task.checked;应该重构.

大致如下:

function TaskList({ className, tasks, setTasks }) {
    const [value, setValue] = useState(''); // <-------------------
  
    return (
      <div className={className}>
        <ul className="grow overflow-y-scroll">
          {tasks.map((task, i) => (
            <Task
              key={task.description} // <-------------------
              description={task.description}
              checked={task.checked} // <-------------------
              onChange={() => {
                setTasks( // <-------------------
                  tasks.map(
                    (task, j) => i !== j ? task : { ...task, checked: !task.checked }
                  )
                );
              }}
            />
          ))}
        </ul>
        <input
          className="my-2 border-b-2 border-blue-300"
          placeholder="Enter task description..."
          value={value} // <-------------------
          onChange={(e) => setValue(e.currentTarget.value)} // <-------------------
        ></input>
        <button
          className="rounded-md bg-blue-400 w-full p-4 text-white text-2xl"
          onClick={() => {
            setTasks([
              ...tasks,
              { description: value, checked: false }, // <-------------------
            ]);
          }}
        >
        ...
function Task({ description, onChange, checked }) { // <-------------------
  return (
    <li className="flex flex-row my-2">
      <input className="mx-2" type="checkbox" onChange={onChange} checked={checked} />  // <-------------------
      <span>{description}</span>
    </li>
  );
}

Javascript相关问答推荐

为什么我的includes声明需要整个字符串?

网页自检测外部元素无法加载

MathJax可以导入本地HTML文档使用的JS文件吗?

在open shadow—root中匹配时,使用jQuery删除一个封闭的div类

Websocket错误—有一个或多个保留位开启:reserved1 = 1,reserved2 = 0,reserved3 = 0

在使用HighChats时如何避免Datatables重新初始化错误?

覆盖TypeScrip中的Lit-Element子类的属性类型

如何将数据块添加到d3力有向图中?

在使用REACT更改了CSS类之后,无法更改CSS样式

让chart.js饼图中的一个切片变厚?

传递方法VS泛型对象VS事件特定对象

处理TypeScrip Vue组件未初始化的react 对象

Chart.js Hover线条在鼠标离开时不会消失

连续添加promise 时,如何在所有promise 都已结算时解除加载覆盖

有没有办法在R中创建一张具有多个色标的热图?

限制数组中每个元素的长度,

如何使用fltter_js将对象作为参数传递给javascrip?

如何缩小函数中联合返回类型的范围

:host::ng-Deep不将样式应用于material 复选框

调试jQuery代码以获取所有行的总和(票证类型)