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

React如何使用Hook操作数组?TodoList渲染及输入异常问题求助

问题排查与修复

你代码里的核心问题如下:

  • 输入框缺失value属性绑定:你只给输入框加了onChange更新task状态,但没有把task值绑定到输入框的value上,每次组件重渲染时输入框就会恢复为空,所以看起来输入的字符直接消失。
  • toDo数组没有用React state声明:普通let变量在组件每次重渲染时都会被重置为[],你修改它既不会触发组件重渲染,也存不住历史添加的任务,所以永远只能看到最新的一个值甚至看不到内容。
  • 第一个toDo.map的回调没有写return:箭头函数用花括号包裹时必须显式return DOM元素,否则map返回的全是undefined,自然渲染不出内容。
  • encours是全局共享状态:你现在所有任务共用同一个encours状态,点击任意一个任务的按钮会导致所有任务的状态同步变更,不符合待办清单的多任务独立状态需求。

修复后的完整代码

import { useState } from 'react';

function Task() {
  // 输入框内容状态
  const [task, setTask] = useState("");
  // 待办列表状态,每个任务存为{id: 唯一标识, content: 内容, status: 状态:en cours/terminé/supprimée}
  const [toDo, setToDo] = useState([]);

  const handleInputTask = (e) => {
    setTask(e.target.value);
  };

  function AddTask() {
    if (task.trim() === "") return;
    // 新增任务到数组,不可直接push,要返回新数组触发重渲染
    setToDo(prev => [...prev, {
      id: Date.now(),
      content: task,
      status: "en cours"
    }]);
    // 新增后清空输入框
    setTask("");
  };

  // 切换指定任务的状态
  const switchTaskStatus = (id, targetStatus) => {
    setToDo(prev => prev.map(item => {
      if (item.id === id) {
        return {...item, status: targetStatus};
      }
      return item;
    }));
  };

  return (
    <div>
      <h2> Ecrivez une nouvelle tâche</h2>
      <div>
        <input value={task} onChange={handleInputTask}></input>
        <button onClick={AddTask}>Valider</button>
        <div className="DivColonne">
          <div className="Colonne">
            <h1>Tâche à faire</h1>
            {/* 筛选状态为en cours的任务 */}
            {toDo.filter(item => item.status === "en cours").map((insertTask) => (
              <div key={insertTask.id}>
                <p>{insertTask.content}</p>
                <button onClick={() => switchTaskStatus(insertTask.id, "terminé")}>en cours</button>
              </div>
            ))}
          </div>
          <div className="Colonne">
            <h1>Tâche en cours</h1>
            {/* 筛选状态为terminé的任务 */}
            {toDo.filter(item => item.status === "terminé").map((insert) => (
              <div key={insert.id}>
                <p>{insert.content}</p>
                <button onClick={() => switchTaskStatus(insert.id, "supprimée")}>terminé</button>
              </div>
            ))}
          </div>
          <div>
            <h1>Tâches terminées</h1>
            {/* 筛选状态为supprimée的任务 */}
            {toDo.filter(item => item.status === "supprimée").map((item) => (
              <p key={item.id}>{item.content}</p>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

export default Task;

主要修改说明

  • 给输入框添加了value={task}绑定,输入内容会和状态同步,不会再出现输入后消失的问题
  • 将toDo改为React state,修改时用展开运算符返回新数组,触发组件重渲染,可正常存储多个任务
  • 给每个任务添加了独立的id和status属性,修改状态时只会影响指定任务,不会全局同步变更
  • 删掉了嵌套的RenderMesTasks组件,直接在父组件内渲染内容,避免作用域问题
  • 修正了map回调的return问题,用小括号包裹DOM隐式return更简洁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 07:39:02