使用 react-bootstrap ListGroup 切换 selected/active 状态
Toggle selected/active state with react-bootstrap ListGroup
我正在使用 React-bootstrap ListGroup.
在 React 中构建多项选择
尽管将项目的 active
属性 设置为 false
,但最后单击的项目在其 active =43=]列表。
我一直在考虑获取对列表项的引用并操作 class 列表,但这太脏了。
我尝试更改 ListGroup.Item
的 variant
属性,但 active class 覆盖了它。我不想修改 css class 定义。
从可用性的角度来看,我更喜欢使用 ListGroup 的 onSelect 处理程序而不是使用 ToggleButton 的 onClick 事件。
您是否尝试过使用 ListGroup 来操作多项选择?
这里是代码的精简版:
import { useState } from "react";
import "./styles.css";
import ListGroup from "react-bootstrap/ListGroup";
import Container from "react-bootstrap/Container";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
import ToggleButton from "react-bootstrap/ToggleButton";
import "bootstrap/dist/css/bootstrap.min.css";
import { cloneDeep } from "lodash";
export default function App() {
const allItems = [
{ id: 1, title: "A" },
{ id: 2, title: "B" },
{ id: 3, title: "C" },
{ id: 4, title: "D" },
{ id: 5, title: "E" }
];
const [selectedItems, setSelectedItems] = useState([
{ id: 2, title: "B" },
{ id: 4, title: "D" }
]);
function toggleSelection(eventKey, e) {
const itemId = parseInt(eventKey?.replace(/^itemSelect_/, ""), 10);
const newSelectedItems = cloneDeep(selectedItems);
const indexInSelection = selectedItems.findIndex(
(sitm) => sitm.id === itemId
);
if (indexInSelection >= 0) {
newSelectedItems.splice(indexInSelection, 1);
} else {
const newItem = allItems.find((itm) => itm.id === itemId);
newSelectedItems.push(newItem);
}
setSelectedItems(newSelectedItems);
}
return (
<div className="App">
<ListGroup onSelect={toggleSelection}>
{allItems.map((itm) => {
return (
<ListGroup.Item
eventKey={`itemSelect_${itm.id}`}
key={`itemSelect${itm.id}`}
active={
selectedItems.find((sitm) => sitm.id === itm.id) !== undefined
}
>
<Container>
<Row>
<Col sm="2">
{" "}
<ToggleButton
className="mx-1"
type="checkbox"
size="sm"
key={`check${itm.id}`}
checked={
selectedItems.find((sitm) => sitm.id === itm.id) !==
undefined
}
value={itm.id}
></ToggleButton>
</Col>
<Col sm="10">{itm.title}</Col>
</Row>
</Container>
</ListGroup.Item>
);
})}
</ListGroup>
</div>
);
}
提供实时预览
在此先感谢您的帮助!
这与 eventKey
和 onSelect
有关 - ListGroup
和 ListGroup.Item
对各种用户操作有一些内部实现,您可以在 [=19= 中看到] 反而。我删除了 ListGroup
上的 onSelect
并在 ListGroup.Item
上添加了 onClick
事件,我们不再需要 eventKey 并直接传递 itm.id
。
我正在使用 React-bootstrap ListGroup.
在 React 中构建多项选择尽管将项目的 active
属性 设置为 false
,但最后单击的项目在其 active =43=]列表。
我一直在考虑获取对列表项的引用并操作 class 列表,但这太脏了。
我尝试更改 ListGroup.Item
的 variant
属性,但 active class 覆盖了它。我不想修改 css class 定义。
从可用性的角度来看,我更喜欢使用 ListGroup 的 onSelect 处理程序而不是使用 ToggleButton 的 onClick 事件。
您是否尝试过使用 ListGroup 来操作多项选择?
这里是代码的精简版:
import { useState } from "react";
import "./styles.css";
import ListGroup from "react-bootstrap/ListGroup";
import Container from "react-bootstrap/Container";
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
import ToggleButton from "react-bootstrap/ToggleButton";
import "bootstrap/dist/css/bootstrap.min.css";
import { cloneDeep } from "lodash";
export default function App() {
const allItems = [
{ id: 1, title: "A" },
{ id: 2, title: "B" },
{ id: 3, title: "C" },
{ id: 4, title: "D" },
{ id: 5, title: "E" }
];
const [selectedItems, setSelectedItems] = useState([
{ id: 2, title: "B" },
{ id: 4, title: "D" }
]);
function toggleSelection(eventKey, e) {
const itemId = parseInt(eventKey?.replace(/^itemSelect_/, ""), 10);
const newSelectedItems = cloneDeep(selectedItems);
const indexInSelection = selectedItems.findIndex(
(sitm) => sitm.id === itemId
);
if (indexInSelection >= 0) {
newSelectedItems.splice(indexInSelection, 1);
} else {
const newItem = allItems.find((itm) => itm.id === itemId);
newSelectedItems.push(newItem);
}
setSelectedItems(newSelectedItems);
}
return (
<div className="App">
<ListGroup onSelect={toggleSelection}>
{allItems.map((itm) => {
return (
<ListGroup.Item
eventKey={`itemSelect_${itm.id}`}
key={`itemSelect${itm.id}`}
active={
selectedItems.find((sitm) => sitm.id === itm.id) !== undefined
}
>
<Container>
<Row>
<Col sm="2">
{" "}
<ToggleButton
className="mx-1"
type="checkbox"
size="sm"
key={`check${itm.id}`}
checked={
selectedItems.find((sitm) => sitm.id === itm.id) !==
undefined
}
value={itm.id}
></ToggleButton>
</Col>
<Col sm="10">{itm.title}</Col>
</Row>
</Container>
</ListGroup.Item>
);
})}
</ListGroup>
</div>
);
}
提供实时预览
在此先感谢您的帮助!
这与 eventKey
和 onSelect
有关 - ListGroup
和 ListGroup.Item
对各种用户操作有一些内部实现,您可以在 [=19= 中看到] 反而。我删除了 ListGroup
上的 onSelect
并在 ListGroup.Item
上添加了 onClick
事件,我们不再需要 eventKey 并直接传递 itm.id
。