繁体   English   中英

Material-UI:如何使受控手风琴表现得像基本手风琴

[英]Material-UI: How to make a Controlled accordion behaves like a Basic accordion

我是初级开发人员,这是我的第一个问题

我正在使用 Controlled 手风琴,因为我需要图标动态更改,但我希望它在展开面板时保持打开状态,即使我已经像基本一样展开了另一个面板。

我知道它与 handleChange 函数有关,但它的逻辑现在超出了我的范围

我正在使用 React

有任何想法吗?

 const [expanded, setExpanded] = React.useState(false);

 const handleChange = (panel) => (event, isExpanded) => {
   setExpanded(isExpanded ? panel : false);
 };

 {grant?.generalRequirementsDetails.length ? (
                   <div className="grant-info-items">
                     <MuiAccordion
                       expanded={expanded === 'panel1'}
                       onChange={handleChange('panel1')}
                     >
                       <AccordionSummary
                         expandIcon={
                           expanded ? (
                             <img src={lessSVG} alt="less" />
                           ) : (
                             <img src={moreSVG} alt="more" />
                           )
                         }
                         aria-controls="panel1bh-content"
                         id="panel1bh-header"
                       >
                         <h3 sx={{ width: '33%', flexShrink: 0 }}>
                           Requisitos generales
                         </h3>
                       </AccordionSummary>
                       <AccordionDetails>
                         {grant?.generalRequirementsDetails.map(
                           (item, idx) => (
                             <div key={idx} className="grant-item">
                               <img src={tickSVG} />
                               <p>{item}</p>
                             </div>
                           ),
                         )}
                       </AccordionDetails>
                     </MuiAccordion>
                   </div>
                 ) : null}

我还有另外几个面板与这个面板类似,所以当我点击一个面板然后再点击另一个面板时,我希望两个面板都打开,除非我再次点击其中一个面板并且该面板像基本手风琴一样折叠

这是我正在谈论的 MUI 组件的链接: https ://mui.com/components/accordion/

谢谢您的帮助 !

看起来手风琴面板由打开和关闭的单一状态控制,因此如果一个正在打开,则其他面板将关闭。

您可以使每个手风琴成为一个单独的组件,这样每个组件都有自己的expanded状态。 或者,使用对象状态分别存储每个手风琴面板的expanded状态。

两个例子的最小演示: stackblitz

使每个手风琴成为一个单独的组件的示例:

export const MyPanel = ({ grant }) => {
  const [expanded, setExpanded] = React.useState(false);
  const handleChange = () => setExpanded((prev) => !prev);
  return (
    <Accordion expanded={expanded} onChange={handleChange}>
      <AccordionSummary
        expandIcon={expanded ? <RemoveIcon /> : <AddIcon />}
        aria-controls="panel1bh-content"
        id="panel1bh-header"
      >
        <h3 sx={{ width: '33%', flexShrink: 0 }}>Requisitos generales</h3>
      </AccordionSummary>
      <AccordionDetails>
        {grant?.generalRequirementsDetails.map((item, idx) => (
          <div key={idx} className="grant-item">
            <p>{`generalRequirementsDetails: ${item}`}</p>
          </div>
        ))}
      </AccordionDetails>
    </Accordion>
  );
};

export default function App() {
  return (
    <div>
      {grant?.generalRequirementsDetails.length ? (
        <div className="grant-info-items">
          {[0, 1, 2].map((item) => {
            return <MyPanel key={item} grant={grant} />;
          })}
        </div>
      ) : null}
    </div>
  );
}

将对象状态用于控件的示例:

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

  const handleChange = (panel) => () => {
    setExpanded((prev) => {
      return { ...prev, [panel]: !!!prev[panel] };
    });
  };

  return (
    <div>
      {grant?.generalRequirementsDetails.length ? (
        <div className="grant-info-items">
          <Accordion
            expanded={!!expanded['panel1']}
            onChange={handleChange('panel1')}
          >
            <AccordionSummary
              expandIcon={!!expanded['panel1'] ? <RemoveIcon /> : <AddIcon />}
              aria-controls="panel1bh-content"
              id="panel1bh-header"
            >
              <h3 sx={{ width: '33%', flexShrink: 0 }}>Requisitos generales</h3>
            </AccordionSummary>
            <AccordionDetails>
              {grant?.generalRequirementsDetails.map((item, idx) => (
                <div key={idx} className="grant-item">
                  <p>{`generalRequirementsDetails: ${item}`}</p>
                </div>
              ))}
            </AccordionDetails>
          </Accordion>
          <Accordion
            expanded={!!expanded['panel2']}
            onChange={handleChange('panel2')}
          >
            <AccordionSummary
              expandIcon={!!expanded['panel2'] ? <RemoveIcon /> : <AddIcon />}
              aria-controls="panel1bh-content"
              id="panel1bh-header"
            >
              <h3 sx={{ width: '33%', flexShrink: 0 }}>Requisitos generales</h3>
            </AccordionSummary>
            <AccordionDetails>
              {grant?.generalRequirementsDetails.map((item, idx) => (
                <div key={idx} className="grant-item">
                  <p>{`generalRequirementsDetails: ${item}`}</p>
                </div>
              ))}
            </AccordionDetails>
          </Accordion>
          <Accordion
            expanded={!!expanded['panel3']}
            onChange={handleChange('panel3')}
          >
            <AccordionSummary
              expandIcon={!!expanded['panel3'] ? <RemoveIcon /> : <AddIcon />}
              aria-controls="panel1bh-content"
              id="panel1bh-header"
            >
              <h3 sx={{ width: '33%', flexShrink: 0 }}>Requisitos generales</h3>
            </AccordionSummary>
            <AccordionDetails>
              {grant?.generalRequirementsDetails.map((item, idx) => (
                <div key={idx} className="grant-item">
                  <p>{`generalRequirementsDetails: ${item}`}</p>
                </div>
              ))}
            </AccordionDetails>
          </Accordion>
        </div>
      ) : null}
    </div>
  );
}

暂无
暂无

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

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