ReactJS函数组件:accordion,允许多个选中的open使用useState

问题描述 投票:0回答:1

我在ReactJS中为手风琴可折叠面板嘲笑了一个简单的逻辑。我试图允许多个可折叠打开但是我无法避免所有可折叠打开和关闭,无论哪个可折叠点击。以下是手风琴在当时只允许一个可折叠的逻辑。

//Accordion.js
import React, { useState } from "react";
import styled, { css } from "styled-components";
import PropTypes from "prop-types";
import Collapse from "./Collapse";
import Header from "./Header";
const Accordion = ({ list, icon}) => {
  const [isActiveIndex, setActiveIndex] = useState(null);
  const toggleItem = index => {
    setActiveIndex(isActiveIndex === index ? null : index);
  };
  return (
    <Wrapper>
      {list.map((item, index) => {
        const checkOpen = isActiveIndex === index;

        return (
          <Container key={index}>
            <Header
              title={item.title}
              icon={icon}
              id={index}
              onClick={toggleItem}
            />
            <Body isOpen={checkOpen}>
              <Collapse isOpen={checkOpen}>{item.content}</Collapse>
            </Body>
          </Container>
        );
      })}
    </Wrapper>
  );
};

我在这里创建了CodeSandBox中的整个模拟:https://codesandbox.io/s/1r2mvk87q

对于初始手风琴我使用useState并检查活动索引 - 对于允许倍数我想我应该检查点击项目的先前状态但我无法将点击的项目作为州的唯一目标被检查。

//AccordionMultiple.js
const AccordionM = ({ list, icon }) => {
  const [isOpen, setOpen] = useState(false);
  const toggleItemM = index => {
    setOpen(prevState => !prevState);
  };

  return (
    <Wrapper>
      {list.map((item, index) => {
        return (
          <Container key={index}>
            <Header
              title={item.title}
              icon={icon}
              id={index}
              onClick={toggleItemM}
            />
            <Body isOpen={isOpen}>
              <Collapse isOpen={isOpen}>{item.content}</Collapse>
            </Body>
          </Container>
        );
      })}
    </Wrapper>
  );
};
javascript reactjs accordion
1个回答
1
投票

为了允许多个可折叠列,您可以使用对象而不是单个索引

const Accordion = ({ list, icon}) => {
  const [isActivePanel, setActivePanel] = useState({});
  const toggleItem = index => {
    setActivePanel(prevState => ({...prevState, [index]: !Boolean(prevState[index])}));
  };
  return (
    <Wrapper>
      {list.map((item, index) => {
        const checkOpen = isActivePanel[index];

        return (
          <Container key={index}>
            <Header
              title={item.title}
              icon={icon}
              id={index}
              onClick={toggleItem}
            />
            <Body isOpen={checkOpen}>
              <Collapse isOpen={checkOpen}>{item.content}</Collapse>
            </Body>
          </Container>
        );
      })}
    </Wrapper>
  );
};
© www.soinside.com 2019 - 2024. All rights reserved.