You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React复选框onChange事件未触发toggleTodo函数问题求助

问题分析与修复方案

你的代码里有两个关键问题导致复选框的onChange事件无法触发:

1. 无效的JSX语法错误

在<ul className="list">后面存在多余的`your text`代码,这会破坏整个JSX的结构,导致列表项渲染异常,进而影响事件绑定逻辑。

2. Label与复选框的关联错误

每个<label>的htmlFor属性固定为item1,但对应的复选框未设置匹配的id属性,且所有列表项的label都指向同一个id,这会造成交互逻辑混乱,甚至可能遮挡复选框的点击区域。

修复后的完整代码

import { useState } from "react";

const App = () => {
  const [newItem, setNewItem] = useState("");
  const [todos, setTodos] = useState([]);

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

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

    setTodos((curr) => {
      return [
        ...curr,
        {
          id: crypto.randomUUID(),
          title: newItem,
          completed: false,
        },
      ];
    });
    setNewItem("");
  };

  const toggleTodo = (id, completed) => {
    console.log("toggleTodo has been invoked");
    setTodos((curr) => {
      return curr.map((todo) => {
        if (todo.id === id) {
          return { ...todo, completed};
        }
        return todo;
      });
    });
  };
    
  return (
    <>
      <form className="new-item-form" onSubmit={handleSubmit}>
        <div className="form-row">
          <label htmlFor="item">New todo</label>
          <input
            type="text"
            name=""
            id="item"
            value={newItem}
            onChange={handleChange}
          />
          <button type="submit" className="btn">
            Add
          </button>
        </div>
      </form>
      <h1 className="header">Todo List</h1>
      <ul className="list">
        {todos.map((todo) => {
          return (
            <li key={todo.id}>
              <label htmlFor={`todo-${todo.id}`}>{todo.title}</label>
              <input 
                type="checkbox" 
                id={`todo-${todo.id}`}
                checked={todo.completed}
                onChange={(e) => toggleTodo(todo.id, e.target.checked)}
              />
              <button className="btn btn-danger">Delete</button>
            </li>
          );
        })}
      </ul>
    </>
  );
};

export default App;

修复说明

  • 移除了<ul>标签后多余的`your text`,确保JSX结构合法。
  • 为每个复选框设置唯一id(格式为todo-${todo.id}),同时将对应label的htmlFor属性匹配该唯一id,实现label与复选框的正确关联,点击label也能切换复选框状态。
  • 保留了你原有的toggleTodo逻辑,修复后点击复选框时该函数会正常触发,待办项的completed状态也会正确更新。

内容的提问来源于stack exchange,提问作者matt smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 22:43:09