简体   繁体   English

我需要根据箭头点击打开和关闭手风琴

[英]I need to open and close accordion based on arrow click

I am using Material UI accordion my issue is if I click on the arrow accordion will get open but again I click on the arrow it will not get closed I need to set it when the user clicks on the arrow according will close and open based on the arrow click check code sandbox link for better understanding.我正在使用 Material UI 手风琴我的问题是如果我点击箭头手风琴会打开但是我再次点击箭头它不会关闭我需要在用户点击箭头时设置它根据将关闭和打开基于箭头单击检查代码沙箱链接以获得更好的理解。

export default function ControlledAccordions() {
  const [expanded, setExpanded] = React.useState(false);

  // const handleChange = (panel) => (event, isExpanded) => {
  //   setExpanded(isExpanded ? panel : false);
  // };
  const handleChange = (pannel) => {
    setExpanded(pannel);
  };
  const panaalData = ["panel1", "panel2", "panel3", "panel4"];
  return (
    <div>
      {panaalData.map((value, i) => {
        return (
          <Accordion expanded={expanded === `panel${i}`}>
            <AccordionSummary
              expandIcon={
                <ExpandMoreIcon
                  onClick={() => {
                    handleChange(`panel${i}`);
                  }}
                  style={{ cursor: "pointer" }}
                />
              }
              aria-controls="panel1d-content"
              id="panel1d-header"
            >
              fdsfdsf
            </AccordionSummary>
            <AccordionDetails>dfdf</AccordionDetails>
          </Accordion>
        );
      })}
    </div>
  );
}

Code SandBox Link 代码沙盒链接

you need to reset panel in that case.在这种情况下,您需要重置面板。 You can do that in change handler.您可以在更改处理程序中执行此操作。

const handleChange = (pannel) => {
   setExpanded(expended === pannel ? '' : pannel);
};

when you click the already expanded panel, it just sets it to be expanded again.当您单击已经展开的面板时,它只是将其设置为再次展开。

you need to check whether the clicked panel is already expanded and if so collapse it instead of expanding it:您需要检查单击的面板是否已经展开,如果是,则折叠它而不是展开它:

  const handleChange = (pannel) => {
    if (expanded === pannel) setExpanded(false);
    else setExpanded(pannel);
  }; 

this work for me:这对我有用:

import React from "react";
import Accordion from "@material-ui/core/Accordion";
import AccordionSummary from "@material-ui/core/AccordionSummary";
import AccordionDetails from "@material-ui/core/AccordionDetails";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";

export default function ControlledAccordions() {
  const [expanded, setExpanded] = React.useState(false);

  // Function to handle the accordion expansion
  const handleChange = (panel) => {
    // If the panel is already expanded, collapse it
    if (expanded === panel) {
      setExpanded(false);
    } else {
      setExpanded(panel);
    }
  };

  const panelData = ["panel1", "panel2", "panel3", "panel4"];

  return (
    <div>
      {panelData.map((value, i) => {
        return (
          <Accordion expanded={expanded === value}>
            <AccordionSummary
              expandIcon={
                <ExpandMoreIcon
                  onClick={() => {
                    handleChange(value);
                  }}
                  style={{ cursor: "pointer" }}
                />
              }
              aria-controls="panel1d-content"
              id="panel1d-header"
            >
              fdsfdsf
            </AccordionSummary>
            <AccordionDetails>dfdf</AccordionDetails>
          </Accordion>
        );
      })}
    </div>
  );
}

Hope this help!希望这有帮助!

Create another component called MyAccordian and keep toggling accordion logic in that component.创建另一个名为MyAccordian的组件,并在该组件中继续切换手风琴逻辑。 That way you don't need to handle toggling for each and every component separately.这样您就不需要分别处理每个组件的切换。

export default function ControlledAccordions() {
  const panaalData = ["panel1", "panel2", "panel3", "panel4"];
  return (
    <div>
      {panaalData.map((value, i) => {
        return <MyAccordian value={value} />;
      })}
    </div>
  );
}

const MyAccordian = ({ value }) => {
  const [expanded, setExpanded] = React.useState(false);

  return (
    <Accordion expanded={expanded}>
      <AccordionSummary
        expandIcon={
          <ExpandMoreIcon
            onClick={() => {
              setExpanded((prev) => !prev);
            }}
            style={{ cursor: "pointer" }}
          />
        }
        aria-controls="panel1d-content"
        id="panel1d-header"
      >
        {value}
      </AccordionSummary>
      <AccordionDetails>{value}</AccordionDetails>
    </Accordion>
  );
};

Working Demo工作演示

编辑 beautiful-browser-5jys6l

export default function ControlledAccordions() {
  // initial state, everything is closed,
  const [expandedIndex, setExpandedIndex] = React.useState(-1);

  // this should be handleClic
  const handleChange = (index) => {
    // in useState, current expandedIndex is passed as the argument
    // whatever we return will be set as the expandedIndex
    setExpandedIndex((currentIndex) => {
      // if any box is open, currentIndex will be that index
      // when I click on the open box, it will set the expandedIndex=-1
      if (currentIndex === index) {
        return -1;
      } else {
        // If I reached here, that means I am on a closed box
        // when I click I swithc the expandedIndex to current box's index
        return index;
      }
    });
  };
  const panaalData = ["panel1", "panel2", "panel3", "panel4"];
  return (
    <div>
      {panaalData.map((value, i) => {
        // when handleChange runs on AccordionSummary expandedIndex===i
        // that means when i click on the current box, it will be open
        const isExpanded = expandedIndex === i;
        return (
          <Accordion expanded={isExpanded}>
            <AccordionSummary
              onClick={() => handleChange(i)}
              expandIcon={
                // I dont know @mui/material too much. 
                // main question is "I need to open and close accordion based on arrow click"
                <ExpandMoreIcon
                  onClick={() => handleChange(i)}
                  style={{ cursor: "pointer" }}
                />
              }
              aria-controls="panel1d-content"
              id="panel1d-header"
            >
              {value}
            </AccordionSummary>
            <AccordionDetails
              style={{ backgroundColor: "green" }}
            >{`box index ${i} is open`}</AccordionDetails>
          </Accordion>
        );
      })}
    </div>
  );
}

proof of work:工作证明:

在此处输入图像描述

const handleChange = (pannel) => {
    setExpanded(!pannel);
  };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM