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
相关产品推荐
相关产品推荐

