如何使用 React 删除列表项(功能组件)
Posted
技术标签:
【中文标题】如何使用 React 删除列表项(功能组件)【英文标题】:How to delete a list item with React (function component) 【发布时间】:2021-12-11 07:49:35 【问题描述】:只是在做一个简单的练习清单,我希望能够点击我清单上的一个项目来删除它。我想我已经很接近了,但无法弄清楚如何从单击的 li 中获取某种数据以将其与我的数组进行比较。
App.js
import useState from "react";
import "./App.css";
import Newtodo from "./NewTodo/NewTodo";
import TodoList from "./TodoList/TodoList";
let INITIAL_TODOS = [
id: "e1", title: "Set up meeting", date: new Date(2021, 0, 14), index: 0 ,
id: "e2",
title: "Doctor appointment",
date: new Date(2021, 2, 14),
index: 1,
,
id: "e3", title: "Work on project", date: new Date(2021, 1, 22), index: 2 ,
id: "e4", title: "Update resume", date: new Date(2021, 6, 14), index: 3 ,
];
const App = () =>
const [todos, setTodos] = useState(INITIAL_TODOS);
const deleteItem = (e) =>
const newTodos = todos.filter((item) => item.index !== 1 /*This works properly with a hardcoded value(1) but how can this be done dynamically as e doesn't seem to have anything useful within it (like e.target.value)*/);
setTodos(newTodos);
;
return (
<div className="App">
<Newtodo />
<TodoList items=todos handleDelete=deleteItem />
</div>
);
;
export default App;
TodoList.js
import "./TodoList.css";
import Todo from "./Todo";
const TodoList = (props) =>
return (
<div className="todo-list">
<ul>
props.items.map((todo, i) => (
<Todo
index=i
key=todo.id
title=todo.title
date=todo.date
handleDelete=props.handleDelete
/>
))
</ul>
</div>
);
;
export default TodoList;
Todo.js
import "./Todo.css";
const Todo = (props) =>
const month = props.date.toLocaleString("en-US", month: "long" );
const day = props.date.toLocaleString("en-US", day: "2-digit" );
const year = props.date.getFullYear();
return (
<li onClick=props.handleDelete className="todo-item">
<h2>props.title</h2>
<span>
day, month, year
</span>
</li>
);
;
export default Todo;
任何帮助或指导将不胜感激!
【问题讨论】:
您必须将id
从Todo
组件传递给其父组件。
【参考方案1】:
您需要传递要删除的元素的索引。在删除处理程序中,按索引不等于传递的索引
的元素过滤const deleteItem = (index) =>
setTodos(todos => todos.filter((item, i) => i !== index));
;
在映射中
const TodoList = (props) =>
return (
<div className="todo-list">
<ul>
props.items.map((todo, i) => (
<Todo
index=i
key=todo.id
title=todo.title
date=todo.date
handleDelete=() => props.handleDelete(i)
/>
))
</ul>
</div>
);
;
改用id
属性可能会更好。
const deleteItem = (id) =>
setTodos(todos => todos.filter((item) => item.id !== id));
;
...
const TodoList = (props) =>
return (
<div className="todo-list">
<ul>
props.items.map((todo, i) => (
<Todo
index=i
key=todo.id
title=todo.title
date=todo.date
handleDelete=() => props.handleDelete(todo.id)
/>
))
</ul>
</div>
);
;
为了避免子组件中的匿名回调,将handleDelete
声明为柯里化函数。
const deleteItem = (id) => () =>
setTodos(todos => todos.filter((item) => item.id !== id));
;
...
const TodoList = (props) =>
return (
<div className="todo-list">
<ul>
props.items.map((todo, i) => (
<Todo
index=i
key=todo.id
title=todo.title
date=todo.date
handleDelete=props.handleDelete(todo.id)
/>
))
</ul>
</div>
);
;
【讨论】:
“为了避免匿名回调” 请注意,柯里化函数仍然返回匿名回调,所以它只是解决了问题,最终可能会变得更糟,性能-wise(重新渲染Todo
与 li
标记)。
我仍然赞成您对id
建议的回答以及正确使用设置器回调表单,而不是像接受的回答所建议的那样使用当前(可能已过时)状态。【参考方案2】:
首先你需要将你的 todo id 传递给句柄 delete 然后你可以在那里访问 id
props.items.map((todo, i) => (
<Todo
index=i
key=todo.id
title=todo.title
date=todo.date
handleDelete=()=> props.handleDelete(todo.id)
/>
))
您在此处访问 id
const deleteItem = (todoId) =>
const newTodos = todos.filter((item) => item.id !== todoId;
setTodos(newTodos);
;
【讨论】:
非常感谢,工作就像一个魅力。我会将其标记为已解决! :)【参考方案3】:在 Todo.js 中添加 data-index
属性
<li data-index=props.index onClick=props.handleDelete className="todo-item">
<h2>props.title</h2>
<span>
day, month, year
</span>
</li>
并在deleteTodo
删除它
const deleteItem = (e) =>
const newTodos = todos.filter((item) => +item.index !== +e.currentTarget.dataset.index)
setTodos(newTodos);
;
【讨论】:
以上是关于如何使用 React 删除列表项(功能组件)的主要内容,如果未能解决你的问题,请参考以下文章
React Native:如何正确地将 renderItem 项传递给 FlatList,以便它们可以在另一个组件中呈现?