首页 > 解决方案 > 单击图标时如何打开每个项目的手风琴?

问题描述

我在reactjs中创建了一个手风琴式组件在这个当我打开第一个切换时,只有一个内容应该打开,当点击第二个切换时,切换一个内容应该关闭并且只切换第二个内容应该打开(只有一个切换应该一次打开)。但在我的情况下,每次打开相同的 div。不知道我哪里做错了?以及如何解决它?下面是我的代码

import React, { useState } from "react";
import { FaPlus, FaMinus } from "react-icons/fa";
import "./FAQ.scss";
import { Collapse } from "reactstrap";

const Question = (props) => {
    const [isOpen, setIsOpen] = useState(false);

    const toggle = () => setIsOpen(!isOpen);

    return (
        <div className="question">
            <div>
                <button onClick={toggle}>
                    {isOpen ? <FaMinus /> : <FaPlus />}
                </button>
            </div>
            <div onClick={toggle} className='title'>
                {props.question}
            </div>
                <Collapse isOpen={isOpen} className='content'>
                    The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for 
                    those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" 
                    by Cicero are also reproduced in their exact original form, accompanied by English 
                    versions from the 1914 translation by H. Rackham.
                </Collapse>
            <hr />
        </div>
    );
};

function FAQ() {
    return (
        <div className="faq" id='faq'>
            <h2>F.A.Q.</h2>
            <div className="faq-section">
                <Question question="Question one" />
                <Question question="Question two" />
                <Question question="Question three" />
                <Question question="Question four" />
                <Question question="Question five" />
            </div>
        </div>
    );
}

export default FAQ;

截图如下 在此处输入图像描述

更新问题

下面是一个网站的链接,底部有常见问题解答部分,我正在尝试像他们一样制作切换功能。 本网站底部的常见问题解答部分

标签: javascriptreactjs

解决方案


问题

这里的问题是所有Question组件都有自己的状态,独立于其他组件。

解决方案

如果您只想一次打开一个Question,则需要解除状态并在FAQ. 因此,打开/扩展的内容只有一个单一的事实来源。

常问问题

isOpen状态和切换处理程序移动到此父组件。使用“id”来打开/关闭要扩展的问题组件。将一个isOpenand toggleprops 传递给每个Question组件并在此处处理 id 逻辑。

function FAQ() {
  const [isOpen, setIsOpen] = useState(null);

  const toggleOpen = id => () => setIsOpen(
    isOpen => isOpen === id ? null : id,
  );

  return (
    <div className="faq" id='faq'>
      <h2>F.A.Q.</h2>
      <div className="faq-section">
        <Question
          question="Question one"
          isOpen={isOpen === 0}
          toggle={toggleOpen(0)}
        />
        <Question
          question="Question two"
          isOpen={isOpen === 1}
          toggle={toggleOpen(1)}
        />
        <Question
          question="Question three"
          isOpen={isOpen === 2}
          toggle={toggleOpen(2)}
        />
        <Question
          question="Question four"
          isOpen={isOpen === 3}
          toggle={toggleOpen(3)}
        />
        <Question
          question="Question five"
          isOpen={isOpen === 4}
          toggle={toggleOpen(4)}
        />
      </div>
    </div>
  );
}

问题

从传递的道具中调用/使用isOpenand 。toggle

const Question = (props) => {
  return (
    <div className="question">
      <div>
        <button onClick={props.toggle}>
          {props.isOpen ? <FaMinus /> : <FaPlus />}
        </button>
      </div>
      <div onClick={props.toggle} className='title'>
        {props.question}
      </div>
      <Collapse isOpen={props.isOpen} className='content'>
        ....
      </Collapse>
      <hr />
    </div>
  );
};

更新

好的,因为您似乎正在努力解决在每个Question组件中呈现相同“内容”的问题,我建议您将所有问题和内容加载到一个数组中并映射它们,而不是对 JSX 进行硬编码。

常问问题

const faqData = [
  {
    question: "Question one",
    content: <div> .... I'm content .... </div>, // <-- anything renderable as a child
  },
  ... etc...
];

function FAQ() {
  const [isOpen, setIsOpen] = useState(null);

  const toggleOpen = id => () => setIsOpen(
    isOpen => isOpen === id ? null : id,
  );

  return (
    <div className="faq" id='faq'>
      <h2>F.A.Q.</h2>
      <div className="faq-section">
        {faqData.map(({ content, question}, index) => (
          <Question
            key={index}
            content={content}
            question={question}
            isOpen={isOpen === index}
            toggle={toggleOpen(index)}
          />
        ))}
      </div>
    </div>
  );
}

问题

const Question = ({ content, question, isOpen, toggle }) => {
  return (
    <div className="question">
      <div>
        <button onClick={toggle}>
          {isOpen ? <FaMinus /> : <FaPlus />}
        </button>
      </div>
      <div onClick={toggle} className='title'>
        {question}
      </div>
      <Collapse isOpen={isOpen} className='content'>
        {content}
      </Collapse>
      <hr />
    </div>
  );
};

编辑如何在点击图标时为每个项目打开手风琴

万一您错过了它,您还需要在项目中的某处导入引导 CSS,以使引导样式、过渡和动画正常工作。

import "bootstrap/dist/css/bootstrap.min.css";

推荐阅读