首页 > 解决方案 > 在 React Accordion 组件中关闭活动元素

问题描述

我正在为我的 Next.js/react 应用程序中的产品页面构建一个简单的手风琴组件。我已经让它大部分工作了,但是当用户点击打开一个新的手风琴项目时,我需要关闭活动项目。这是我的组件的样子:

import React, { useRef, useState } from 'react';

import css from 'classnames';

import s from './ProductAccordion.module.scss';

interface FeatureProps {
  title: string;
  copy: string;
}

export const ProductAccordion = ({ content }: any) => {
  return (
    <div className={s.productAccordion}>
      {content.features.map((feature: FeatureProps) => {
        const [active, setActive] = useState(false);
        const activeClass = active ? 'active' : '';

        const toggleAccordion = () => {
          setActive(!active);
        };

        return (
          <div
            className={css(s.productAccordion__section, s[activeClass])}
            key={feature.title}
          >
            <button className={s.sectionTitle} onClick={toggleAccordion}>
              <p className={s.sectionTitle__title}>{feature.title}</p>
              <span className={s.button} />
            </button>

            <div className={css(s.sectionContent, s[activeClass])}>
              <div className={s.sectionContent__copy}>{feature.copy}</div>
            </div>
          </div>
        );
      })}
    </div>
  );
};

单击新的手风琴项时,如何关闭活动的手风琴项?谢谢!

标签: javascriptreactjsreact-hooksuse-state

解决方案


我会建议:

  • 将您的useState钩子移到更高的级别
  • 而不是“活动”是一个布尔值,让它成为一个字符串,你可以用它来识别哪个项目应该是活动的
  • 希望 afeature具有唯一标识符,例如 id 或您可以用来识别的东西

您可以执行以下操作:

export const ProductAccordion = ({ content }: any) => {
  const [active, setActive] = useState(''); // set up your useState here, so its value is available to all children elements

  return (
    <div className={s.productAccordion}>
      {content.features.map((feature: FeatureProps) => {

        const isActive = active === feature.id // feature.id here is just a stand in for some unique identifier that each feature has
     
        const activeClass = isActive ? 'active' : '';

        const toggleAccordion = () => {
          if (isActive) {
           setActive(''); // if the current item is active, and you toggle it, close the accordian
          } else {
           setActive(feature.id) // if the current item is not active, and you toggle it, open this section
          }
        };

        return (
          <div>
           {/* your code here */}
    </div>
  );
};

当然,您可以采用许多方法,我敢肯定比这更优雅的方法存在。但这应该有望使您朝着正确的方向前进!


推荐阅读