使用功能组件/挂钩从 React 中的数组中删除特定项目
Posted
技术标签:
【中文标题】使用功能组件/挂钩从 React 中的数组中删除特定项目【英文标题】:Deleting Specific Item From Array in React using Functional Components/Hooks 【发布时间】:2021-03-13 02:42:24 【问题描述】:我正在尝试删除数组中的一项。但是,我的删除按钮没有执行我的代码,并且数组保持不变。我不知道该怎么办。
我的代码如下:
//App.js
import React, useState from "react";
import Overview from "./components/Overview";
function App()
const [task, setTask] = useState("");
const [tasks, setTasks] = useState([]);
function handleChange(e)
setTask(e.target.value);
function onSubmitTask(e)
e.preventDefault();
setTasks(tasks.concat(task));
setTask("");
//error happening here????---------------------------------------------------
function removeTask(itemId)
setTasks(prevState => prevState.filter(( id ) => id !== itemId));
return (
<div className="col-6 mx-auto mt-5">
<form onSubmit=onSubmitTask>
<div className="form-group">
<label htmlFor="taskInput">Enter task</label>
<input
onChange=handleChange
value=task
type="text"
id="taskInput"
className="form-control"
/>
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary">
Add Task
</button>
</div>
</form>
<Overview tasks=tasks removeTask=removeTask />
</div>
);
export default App;
子组件:
import React from "react";
function Overview(props)
const tasks, removeTask = props;
console.log(tasks)
return (
<>
tasks.map((task, index) =>
return (
<>
<p key=index>
#index + 1 task
</p>
//this onClick isn't doing anything-------------------------------------
<button onClick=() => removeTask(index)>Delete Task</button>
</>
);
)
</>
);
export default Overview;
我的“任务”状态给了我一个数组,里面的项目是字符串。但是,当我尝试过滤数组时,它不起作用。因此,我没有按值过滤,而是尝试按 id/index 过滤。由于索引会匹配它,我认为这会从数组中删除该项目,即使只有一个项目,它也不会删除任何内容,并且删除按钮只是控制台记录给定的数组。
任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:问题
您的 delete 方法使用了一个项目 id,但您在按钮的 onClick
处理程序中向它传递了一个索引。
解决方案
在id
或索引中选择一个或另一个,并保持一致。
使用id
function removeTask(itemId)
setTasks(prevState => prevState.filter(( id ) => id !== itemId));
...
<button onClick=() => removeTask(task.id)>Delete Task</button>
使用索引
function removeTask(itemIndex)
setTasks(prevState => prevState.filter((_, index) => index !== itemIndex));
...
<button onClick=() => removeTask(index)>Delete Task</button>
由于您的任务看起来不是具有id
属性的对象,因此我建议在您的任务中添加id
。这将在您以后从列表中成功删除任务时为您提供帮助,因为您还希望不使用数组索引作为反应键,因为您希望改变您的任务数组。
App.js
import v4 as uuidV4 from 'uuid';
...
function onSubmitTask(e)
e.preventDefault();
setTasks(prevTasks => prevTasks.concat(
id: uuidV4(), // <-- generate new id
task
));
setTask("");
function removeTask(itemId)
setTasks(prevState => prevState.filter(( id ) => id !== itemId));
孩子
function Overview( tasks, removeTask )
return (
tasks.map(( id, task , index) => // <-- destructure id & task
return (
<Fragment key=id> // <-- react key on outer-most element
<p>
#index + 1 task
</p>
<button onClick=() => removeTask(id)>Delete Task</button>
</>
);
)
);
【讨论】:
【参考方案2】:我认为你需要在这里传递taskId
而不是index
<button onClick=() => removeTask(task.id /*index*/)>Delete Task</button>
因为removeTask
函数处理的是taskId
而不是index
但是看起来你在tasks
上没有id
字段,即使你假设它在setTasks(prevState => prevState.filter(( id ) => id !== itemId));
中,所以如果你想继续按索引删除任务,请更改removeTask
如下。
function removeTask(index) // remove by index
setTasks(prevState =>
const tasks = [...prevState]; // create new array based on current tasks
tasks.splice(index, 1); // remove task by index
return tasks; // return altered array
);
demo
【讨论】:
以上是关于使用功能组件/挂钩从 React 中的数组中删除特定项目的主要内容,如果未能解决你的问题,请参考以下文章