我有一个显示列表的表格。 每行有 3 列:item
、delete-button-1
、delete-button-2
。 将鼠标悬停在删除按钮上时,相应的项目以红色突出显示。
我正在使用 React HookuseState
来存储悬停删除按钮的行的索引。
我有两个删除按钮的实现,唯一的区别是onClick
属性。 两种实现都有问题。
删除按钮:实现 1
- 将项目添加到列表
- 删除所有项目
- 向列表中添加新项
问题是新列表的第一项以红色突出显示,直到悬停删除按钮才会删除。
删除按钮:实现 2
- 将项目添加到列表
- 删除项目
问题是,尽管下一行的删除按钮代替了已删除行的删除按钮,但在重新悬停此删除按钮之前,该项目不会突出显示。
let id = 0
const {useState} = React
const Table = () => {
const [list, setList] = useState([])
const [warningIndex, setWarning] = useState(null)
const rows = list.map((item, index) => {
const rowClass = (warningIndex === index) ? "warning" : ""
return (
<tr key={index}>
<td className={rowClass}>{item}</td>
<td
className="delete-button"
onMouseEnter={() => setWarning(index)}
onMouseLeave={() => setWarning(null)}
onClick={() => setList([...list.slice(0, index), ...list.slice(index + 1)])}>
-
</td>
<td
className="delete-button"
onMouseEnter={() => setWarning(index)}
onMouseLeave={() => setWarning(null)}
onClick={() => {
setList([...list.slice(0, index), ...list.slice(index + 1)])
setWarning(null)
}}>
-
</td>
</tr>
)
})
return (
<table>
<tbody>
<tr>
<td
className="add-button"
colSpan="3"
onClick={() => setList([...list, id++])}>
+
</td>
</tr>
{rows}
</tbody>
</table>
)
}
ReactDOM.render(<Table/>, document.getElementById('root'));
table {
width: 200px;
border-collapse: collapse;
}
td {
padding: 4px 8px;
border: 1px solid lightgrey;
}
td.add-button, td.delete-button {
cursor: pointer;
width: 1%;
}
td.add-button:hover {
background-color: lightgrey;
}
td.add-button:active {
background-color: darkgrey;
}
td.delete-button:hover {
background-color: #ffcdd2;
}
td.delete-button:active, td.warning {
background-color: #ef9a9a;
}
<script <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
我想要一个没有任何这些问题的删除按钮的实现。我只想要一个删除按钮,这两个是我尝试过的。
每当你在 react 中使用 index 作为键时,它都有可能导致问题,尤其是在添加和删除组件时。
return (
<tr key={index}>
使用唯一键可能会解决您的问题。更多关于反应键 反应键
这个怎么样?如果检查列表为空。=)
let id = 0
const {useState} = React
const Table = () => {
const [list, setList] = useState([])
const [warningIndex, setWarning] = useState(null)
const rows = list.map((item, index) => {
const rowClass = (warningIndex === index) ? "warning" : ""
return (
<tr key={index}>
<td className={rowClass}>{item} - index: {index}</td>
<td
className="delete-button"
onMouseEnter={() => setWarning(index)}
onMouseLeave={() => setWarning(null)}
onClick={() => {
const newList = [...list.slice(0, index), ...list.slice(index + 1)]
if (newList.length === 0){
setWarning(null)
}
setList(newList)
}}>
-
</td>
</tr>
)
})
return (
<table>
<tbody>
<tr>
<td
className="add-button"
colSpan="3"
onClick={() => setList([...list, id++])}>
+
</td>
</tr>
{rows}
</tbody>
</table>
)
}
ReactDOM.render(<Table/>, document.getElementById('root'));
table {
width: 200px;
border-collapse: collapse;
}
td {
padding: 4px 8px;
border: 1px solid lightgrey;
}
td.add-button, td.delete-button {
cursor: pointer;
width: 1%;
}
td.add-button:hover {
background-color: lightgrey;
}
td.add-button:active {
background-color: darkgrey;
}
td.delete-button:hover {
background-color: #ffcdd2;
}
td.delete-button:active, td.warning {
background-color: #ef9a9a;
}
<script <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>