使用 react-bootstrap ListGroup 切换 selected/active 状态

Toggle selected/active state with react-bootstrap ListGroup

我正在使用 React-bootstrap ListGroup.

在 React 中构建多项选择

尽管将项目的 active 属性 设置为 false,但最后单击的项目在其 active =43=]列表。

我一直在考虑获取对列表项的引用并操作 class 列表,但这太脏了。

我尝试更改 ListGroup.Itemvariant 属性,但 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>
  );
}

Code Sandbox

提供实时预览

在此先感谢您的帮助!

这与 eventKeyonSelect 有关 - ListGroupListGroup.Item 对各种用户操作有一些内部实现,您可以在 [=19= 中看到] 反而。我删除了 ListGroup 上的 onSelect 并在 ListGroup.Item 上添加了 onClick 事件,我们不再需要 eventKey 并直接传递 itm.id