如何访问 div 目标以切换列表组项目的样式?

How to access a div target to toggle styling for a list group item in react?

我正在尝试构建一组您可以使用 react-bootstrap 单击打开和关闭的项目,但在我的函数中访问 ListGroup.Item 的目标值时遇到问题。基本上我想:

  1. 单击特定项目
  2. 点击后将该项目变为绿色
  3. 如果任何其他项目是绿色的,则应删除颜色,以便只有最近单击的项目是绿色的

我正在尝试使用 handleCheck 函数来执行此操作,该函数使用目标值来切换 json 属性 但无法使其工作。 event.target.value 正在显示 undefined,我不确定如何进行这项工作。

这是代码的一个工作示例:

https://codesandbox.io/s/targetvalue-zqrkz?file=/src/App.js:1070-1071

可以直接在accordion组件中传递value

import React, { useState } from "react";
import {
  Accordion,
  Card,
  ListGroup,
  DropdownButton,
  Dropdown,
  Image
} from "react-bootstrap";
import { FaChevronCircleDown, FaChevronCircleUp } from "react-icons/fa";
import classes from "./accordian.module.css";

const MainMenu = (props) => {
  const [opened, setOpened] = useState(true);

  const testingSmthFin = (x) => {
    props.testingSmthSec(x);
  };

  const handleTimer = (x) => {
    props.testingTimer(x);
  };

  let dropDown = null;
  if (props.regions) {
    dropDown = (
      <div>
        {props.regions.map((region, i) => {
          return (
            <div key={i}>
              <ListGroup.Item
                value={region.region}
                style={{
                  backgroundColor: region.isChecked ? "#90EE90" : "White"
                }}
                onClick={(e) => props.handleCheck(region.region, i)} //<------------------
              >
                {region.region}
              </ListGroup.Item>
            </div>
          );
        })}
      </div>
    );
  }

  return (
    <Accordion
      defaultActiveKey={props.showAccordian}
      className={classes.mainMenu}
    >
      <Card style={{ padding: 10, backgroundColor: "#ffffff78" }}>
        <Accordion.Toggle
          as={Card.Header}
          eventKey="0"
          style={{ padding: 10, backgroundColor: "#3f4042ba" }}
          onClick={() => setOpened(!opened)}
        >
          <text style={{ color: "beige", fontWeight: "bolder" }}> </text>
          <text style={{ color: "beige" }}>: MY ACCORDIAN </text>
          {opened ? (
            <FaChevronCircleUp color="white" />
          ) : (
            <FaChevronCircleDown color="white" />
          )}
        </Accordion.Toggle>
        <Accordion.Collapse eventKey="0">
          <Card.Body
            style={{
              padding: 10,
              backgroundColor: "white",
              borderRadius: "3%"
            }}
          >
            <ListGroup>
              <ListGroup.Item></ListGroup.Item>
            </ListGroup>
          </Card.Body>
        </Accordion.Collapse>
        <Accordion.Collapse eventKey="0">
          <Card.Body
            style={{
              padding: 10,
              backgroundColor: "white",
              marginTop: 10,
              borderRadius: "3%"
            }}
          >
            <Card.Title style={{ textAlign: "center" }}>
              Check region
            </Card.Title>
            <ListGroup>
              {/* <ListGroup.Item 
                onClick={props.sliceGeo} 
                style={{ backgroundColor: props.checked ? '#90EE90' : 'White' }} 
              >Citywide
              {
                props.checked ?
                <Image
                  style={{marginLeft: '50%'}} 
                  src={checked} 
                  width="20"
                  height="20"
                /> : <div></div>
              }      
              </ListGroup.Item> */}
              {dropDown}
              {/* <ListGroup.Item >Midtown</ListGroup.Item>
              <ListGroup.Item>Queens</ListGroup.Item>
              <ListGroup.Item>Brooklyn</ListGroup.Item>
              <ListGroup.Item>Bronx</ListGroup.Item>
              <ListGroup.Item>Staten Island</ListGroup.Item> */}
            </ListGroup>
          </Card.Body>
        </Accordion.Collapse>
      </Card>
    </Accordion>
  );
};

export default MainMenu;
handleCheck = (value, key) => {                      // <---------------------
    //copy all items
    let regions = [...this.state.regions];
    //extract the itemn we care about
    let item = { ...regions[key] };

    //for the extacted item, check it
    //item.isChecked = !item.isChecked;

    //MY ATTEMPT BELOW
    console.log(value);                         // <---------------------------
    // regions.map((item) => {
    //   if (item.region === event.target.value) {
    //     item.isChecked = true;
    //   } else {
    //     item.isChecked = false;
    //   }
    // });

    //reassign value
    regions[key] = item;

    this.setState({ regions });
    console.log(regions);
  };

最终输出:

import React, { Component } from "react";
import Accordian from "./Accordian";

const data = [
  { region: "Citywide", isChecked: false },
  { region: "Midtown", isChecked: false },
  { region: "Queens", isChecked: false },
  { region: "Brooklyn", isChecked: false },
  { region: "Bronx", isChecked: false },
  { region: "Staten Island", isChecked: false }
];
class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      regions: data
    };
  }

  handleCheck = (event, key) => {
    // reset all values of regions
    let regions = [...data];
    let item = { ...regions[key], isChecked: true };
    // ☝ set the isChecked value of selected item and we are done.
    console.log("regions[key]", regions[key]);
    regions[key] = item;
    this.setState({ regions }, () => console.log("key:", regions));
  };

  render() {
    return (
      <div>
        <Accordian
          regions={this.state.regions}
          handleCheck={this.handleCheck}
        />
      </div>
    );
  }
}

export default App;

工作应用:Codesandbox Link