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

React中如何用Hook将对象推入数组、修改状态并实现排序?

问题梳理

  • 第一个问题:handleInput写法错误,直接把task对象覆盖为输入框的字符串,所以你推入数组的根本不是完整对象。你原本的task是包含task和etat属性的对象,输入时直接赋值字符串会把结构冲掉。
  • 第二个问题:修改状态的逻辑错误。你现在的switchEnCours、deleteTask修改的是全局的单个task状态,不是todoList里对应条目的状态,也没有区分要修改的是哪一个任务,根本改不到列表里的值。
  • 第三个问题:代码里用到的encours变量完全没有定义,运行会直接报错。
  • 第四个问题:排序不需要用map.sort,sort是数组本身的方法,你可以先对todoList做排序,再调用map遍历渲染就可以。
  • 额外注意:useState更新是异步的,你在AddTask里调用setTodoList之后立刻打印todoList拿不到最新值,你已经写了useEffect监听打印就没问题。

修复方案

1. 修复输入逻辑,保留task对象结构

const handleInput = (e) => {
  // 只修改task属性,保留etat的值
  setTask(prev => ({...prev, task: e.target.value}));
};

2. 新增任务时加唯一标识,方便后续修改

const AddTask = (e) => {
  // 给每个任务加唯一id,方便后续查找修改
  const newTask = {...task, id: Date.now()}
  setTodoList([...todoList, newTask]);
  // 加完清空输入框,方便下次输入
  setTask({ task: "", etat: "en cours" });
};

3. 重写状态修改逻辑,定向更新列表对应条目

const switchEnCours = (taskId) => {
  setTodoList(prev => prev.map(item => {
    if(item.id === taskId) {
      return {...item, etat: "terminé"}
    }
    return item
  }))
};

const deleteTask = (taskId) => {
  setTodoList(prev => prev.map(item => {
    if(item.id === taskId) {
      return {...item, etat: "supprimée"}
    }
    return item
  }))
};

4. 修复渲染逻辑,按状态过滤+可选排序

删除不存在的encours变量判断,直接根据任务自身的etat属性过滤渲染到对应列,需要排序的话在map前加sort方法即可:

return (
  <div>
    <input onChange={handleInput} value={task.task}></input>
    <button onClick={AddTask}>Valider</button>
    <div className="DivColonne">
      <div className="Colonne">
        <h1>Tâche à faire</h1>
        {todoList
          .filter(item => item.etat === "en cours")
          // 按任务名称排序,不需要直接删掉这行即可
          .sort((a,b) => a.task.localeCompare(b.task))
          .map((insertTask) => {
            return (
              <div key={insertTask.id}>
                <p>{insertTask.task}</p>
                <button onClick={() => switchEnCours(insertTask.id)}>{insertTask.etat}</button>
              </div>
            );
          })}
      </div>
      <div className="Colonne">
        <h1>Tâche en cours</h1>
        {todoList
          .filter(item => item.etat === "terminé")
          .map((insert) => {
            return (
              <div key={insert.id}>
                <p>{insert.task}</p>
                <button onClick={() => deleteTask(insert.id)}>{insert.etat}</button>
              </div>
            );
          })}
      </div>
      <div>
        <h1>Tâches terminées</h1>
        {todoList
          .filter(item => item.etat === "supprimée")
          .map(item => <p key={item.id}>{item.task}</p>)
        }
      </div>
    </div>
  </div>
);

内容的提问来源于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 10:48:04