我不明白如何使用 deleteItem
函数删除我们的 items 数组中被点击的项目。
我卡住的地方是我不明白如何获取我点击的 <li>
的索引或文本,以便我可以在我的过滤器方法中使用它来返回一个新数组,而不需要被点击的项目。
我尝试使用道具,但这不起作用。我不明白 deleteItem 函数如何与 todoitem 组件及其其余部分相关联。
import React, { useState } from "react";
import ToDoItem from "./ToDoItem";
function App() {
const [inputText, setInputText] = useState("");
const [items, setItems] = useState([]);
function handleChange(event) {
const newValue = event.target.value;
setInputText(newValue);
}
function addItem() {
setItems((prevItems) => {
return [...prevItems, inputText];
});
setInputText("");
}
function deleteItem() {
// setItems((prevState) => {
// return prevState.filter(function (item) {
// return item === props.item;
// });
// });
// console.log(items[2]);
console.log();
}
return (
<div className="container">
<div className="heading">
<h1>To-Do List</h1>
</div>
<div className="form">
<input onChange={handleChange} type="text" value={inputText} />
<button onClick={addItem}>
<span>Add</span>
</button>
</div>
<div>
<ul>
{items.map((todoItem, index) => (
<ToDoItem
key={index}
id={index}
item={todoItem}
deleteItem={deleteItem}
/>
))}
</ul>
</div>
</div>
);
}
export default App;
import React from "react";
function ToDoItem(props) {
return <li onClick={props.deleteItem}>{props.item}</li>;
}
export default ToDoItem;
答案 0 :(得分:1)
我总是这样做 - 这是一个多一点的代码,但你最终不会为每个项目都有一个单独的 delete
函数,或者必须处理抓取 DOM 树(parentNode
和朋友).
<li data-item-index={props.id} ...>
function deleteItem(ev) {
const itemIndex = parseInt(ev.target.dataset.itemIndex, 10);
setItems([
...items.slice(0, itemIndex),
...items.slice(itemIndex + 1)
]);
}
编辑:虽然超出了这个问题的范围,但值得一提的是:
始终尽量避免 onClick={() => deleteItem(props.id)}
样式的回调,尤其是在呈现项目列表时。这些对于快速原型设计、在线示例等很有用 - 但在实际应用程序中,您几乎总是应该执行以下操作:
const deleteItem = useCallback(() => { ... }, []);
<li onClick={deleteItem}>...</li>
<块引用>
注意:这不是“过早优化”,它是您每次需要回调时使用的一组额外按键。
为了避免违反计算机科学的某些教条规则,您应该创建辅助函数来设置和检索值。将所有内容放在一个过于冗长的答案中:
const setItemIdAttr = (id) => ({ 'data-item-id': id });
const getItemIdFromAttr = (el) => parseInt(el.dataset.itemId, 10);
const deleteItem = useCallback((ev) => {
const itemIndex = getItemIdFromAttr(ev.target);
setItems((oldItems) => [
...oldItems.slice(0, itemIndex),
...oldItems.slice(itemIndex + 1)
]);
}, []);
<li {...setItemIdAttr(id)} onClick={deleteItem} ...>
答案 1 :(得分:0)
您可以访问使用 li
点击的 event.target
项目:
function deleteItem(event) {
const item = event.target
console.log("Item :", item);
console.log("Index :", Array.from(item.parentNode.children).indexOf(item));
}
function ToDoItem(props) {
return <li onClick={props.deleteItem}>{props.item}</li>;
}
function App() {
const [inputText, setInputText] = React.useState("");
const [items, setItems] = React.useState([]);
function handleChange(event) {
const newValue = event.target.value;
setInputText(newValue);
}
function addItem() {
setItems((prevItems) => {
return [...prevItems, inputText];
});
setInputText("");
}
function deleteItem(event) {
const listItem = event.target
const listItemIndex = Array.from(listItem.parentNode.children).indexOf(listItem)
setItems((prevState) => {
return prevState.filter(function (item, index) {
return index !== listItemIndex
});
});
console.log("Item :", listItem);
console.log("Index :", listItemIndex);
}
return (
<div className="container">
<div className="heading">
<h1>To-Do List</h1>
</div>
<div className="form">
<input onChange={handleChange} type="text" value={inputText} />
<button onClick={addItem}>
<span>Add</span>
</button>
</div>
<div>
<ul>
{items.map((todoItem, index) => (
<ToDoItem
key={index}
id={index}
item={todoItem}
deleteItem={deleteItem}
/>
))}
</ul>
</div>
</div>
);
}
ReactDOM.render(<App />, document.querySelector('#app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>
答案 2 :(得分:-1)
这就是我的处理方式,因为您的项目没有 id,只需传递索引就可以了
function deleteItem(index) {
let aux = items;
items.splice(index, 1);
setItems([...aux]);
}
<ToDoItem
key={index}
id={index}
item={todoItem}
deleteItem={deleteItem.bind(this, index)}
/>