Компонент функции ReactJS: аккордеон, допускает несколько выбранных открытых с помощью useState - PullRequest
0 голосов
/ 01 марта 2019

Я издевался над простой логикой для складных панелей гармошки в 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>
  );
};

1 Ответ

0 голосов
/ 01 марта 2019

Чтобы можно было использовать несколько разборных столбцов, вы можете использовать объект вместо одного индекса

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>
  );
};
...