React - 如何更改当前单击项目的手风琴标题文本

React - How to change the text of accordion heading of the current clicked item

我正在制作一个简单的 Reactjs 手风琴应用程序,其中完成了每个单独项目的折叠和展开。

要求:

一个简单的要求是我需要根据点击将标题文本切换为 ExpandShrink .

如果我们单击任何项​​目,那么内容将被显示,在这种情况下,文本将变为收缩,因为手风琴被打开,所以收缩标题是为关闭手风琴而给出的。

完整的工作示例:

https://codesandbox.io/s/react-accordion-forked-lcyr0

在上面的示例中,我使用了以下代码来更改文本,

Accordion.js

import React, { useState } from "react";
import Text from "./text";
import Heading from "./heading";
import getAccordion from "./GetAccordion";

const Accordion = getAccordion(1);

const accordionData = [
  {
    id: 1,
    content: "This is a first content"
  },
  {
    id: 2,
    content: "This is a second content"
  },
  {
    id: 3,
    content: "This is a third content"
  }
];

const NormalAccordion = () => {
  const [toggleValue, setToggleValue] = useState(-1);

  const toggleHandler = (index) => {
    setToggleValue(index);
  };

  return (
    <div>
      {accordionData.map((item, index) => (
        <Accordion>
          <Heading>
            <div
              style={{ padding: "10px", cursor: "pointer" }}
              className="heading"
              onClick={() => toggleHandler(index)}
            >
              {toggleValue !== index ? `Expand` : `Shrink`}
            </div>
          </Heading>
          <Text>{item.content}</Text>
        </Accordion>
      ))}
    </div>
  );
};

export default NormalAccordion;

这行 {toggleValue !== index ? `Expand` : `Shrink`} 更改了一次文本,但之后在进一步切换标题时不会进行任何更改(Expand/Shrink)。

请帮助我实现根据相应的点击在展开和收缩之间切换文本的结果。

如果该项目已被点击,您应该重置 toggleValue :

  const toggleHandler = (index) => {

    index===toggleValue?setToggleValue(-1): setToggleValue(index);
  };

然后使用条件渲染当前内容:

<Text>{toggleValue === index && item.content}</Text>

并将 Text 组件简化为这个:

<div style={{ ...this.props.style }}>
        <div className={`content ${this.props.text ? "open" : ""}`}>
          {this.props.children}
        </div>
      </div>

您应该使用布尔值,因为手风琴可以有 2 个值。

想法:

  • 创建一个定义展开/折叠行为的独立手风琴组件。
  • 创建调用此组件的包装器视图组件。
  • 从此视图中将您的数据作为道具传递,而不是使用本地硬编码对象。

这种方法的好处是您有 2 个仅适用于道具的模块化组件。这些可以稍后导出到它们自己的独立库。

理想情况下,一个组件应该是哑的,并且应该只知道它自己基于状态和道具的行为。

Updated sandbox

  • 手风琴组件更改
const [toggleValue, setToggleValue] = useState(false);

const toggleHandler = () => {
  setToggleValue(!toggleValue);
};
  • 手风琴视图更改
const AccordionView = ({ accordionData }) => {
  return (
    <div>
      {accordionData.map((item) => (
        <NormalAccordion content={item.content} />
      ))}
    </div>
  );
};
  • 常量:我创建了一个名为常量的文件夹,用于保存硬编码对象,然后我们使用 index.js
  • 中的 props 传递它
export const accordionData = [{
    id: 1,
    content: "This is a first content"
  },
  {
    id: 2,
    content: "This is a second content"
  },
  {
    id: 3,
    content: "This is a third content"
  }
];
  • index.js
  • 的变化
import { accordionData } from '../constants/accordion-data'

...

<NormalAccordion accordionData={ accordionData } />