唯一地折叠每个按钮,而不是一次折叠

时间:2019-05-09 15:35:44

标签: reactjs button event-handling state collapsable

我有一个<div>标签,其中包含各种按钮。单击每个按钮时,将显示一个react变量。我的问题是,每当我单击任何按钮时,都会显示所有隐藏的文本;但是,我只希望按钮在单击时显示其隐藏文本,以使它们具有独特的行为。

我尝试了一些条件渲染的方法,但是我不确定如何正确地进行攻击。

我有一个为每个教堂创建按钮的功能。这是该功能:

  createButtonsForChurches(arr) {
    var listOfButtons = [];

    for (var i = 1; i < arr.length; i++) { // loop through each church

      var currentButton = (
        <div>
          <button onClick={this.toggle} className="churchButton">{arr[i].name}</button>
          {
            this.state.on && (
              <div className="allContent">
                <div className="individualContent">
                  {(arr[i].femaleStudents[0]) && this.createContentParagraphTextForArray(arr[i].femaleStudents, "Female Students")}
                </div>
                <div className="individualContent">
                  {(arr[i].femaleLeaders[0]) && this.createContentParagraphTextForArray(arr[i].femaleLeaders, "Female Leaders")}
                </div>
                <div className="individualContent">
                  {(arr[i].maleStudents[0]) && this.createContentParagraphTextForArray(arr[i].maleStudents, "Male Students")}
                </div>
                <div className="individualContent">
                  {(arr[i].maleLeaders[0]) && this.createContentParagraphTextForArray(arr[i].maleLeaders, "Male Leaders")}
                </div>
              </div>
            )
          }
      </div>
      );

      listOfButtons.push(currentButton);

    }

    return listOfButtons;
  }

您还可以看到为onClick属性调用的切换功能。这是我的切换方法和构造函数:

  constructor(props) {
    super(props);
    this.toggle = this.toggle.bind(this);
    this.state = {
      on: false
    }
  }

  toggle() {
    this.setState({
      on: !this.state.on
    });
  }

我不想放太多代码并使事情复杂化-arr是一个对象数组。这些对象包含4个不同的数组,并且每个数组都包含不同数量的对象。所以-arr是教堂的列表,其中包含教堂作为对象,每个教堂包含4个数组(男女学生和领袖),并且在这4个数组中的每个数组中,都有成员作为对象,无论它们属于哪里

我不知道如何仅显示单击的按钮的隐藏文本。希望有帮助。

1 个答案:

答案 0 :(得分:1)

您必须为按钮创建一个数组,并赋予属性isHidden以便在切换时显示/隐藏数据。这是您问题的有效解决方案。

class App extends React.Component {
  state = {
    buttons: []
  };
  arr = [
    {
      name: "churchName1",
      femaleStudents: ["student1", "student1"],
      femaleLeaders: ["leaders1", "leaders1"],
      maleStudents: ["student1", "student1"],
      maleLeaders: ["leaders1", "leaders1"]
    },
    {
      name: "churchName2",
      femaleStudents: ["student2", "student2"],
      femaleLeaders: ["leaders2", "leaders2"],
      maleStudents: ["student2", "student2"],
      maleLeaders: ["leaders2", "leaders2"]
    },
    {
      name: "churchName3",
      femaleStudents: ["student3", "student3"],
      femaleLeaders: ["leaders3", "leaders3"],
      maleStudents: ["student3", "student3"],
      maleLeaders: ["leaders3", "leaders3"]
    }
  ];
  componentDidMount() {
    // create buttons array
    let buttons = [];
    for (let item of this.arr) {
      let buttonObj = { id: item.name, isHidden: true };
      buttons.push(buttonObj);
    }
    this.setState({ buttons });
  }
  createContentParagraphTextForArray = (para1, para2) => {
    return (
      <div>
        {para1}&nbsp; {para2}
      </div>
    );
  };
  createButtonsForChurches = arr =>
    arr.map((item, index) => {
      let isHidden =
        this.state.buttons.length > 0
          ? this.state.buttons[index].isHidden
          : true;
      return (
        <div key={item.name}>
          <button
            onClick={() => this.clickHandler(item.name)}
            className="churchButton"
          >
            {item.name}
          </button>
          {!isHidden && (
            <div className="allContent">
              <div className="individualContent">
                {item.femaleStudents[0] &&
                  this.createContentParagraphTextForArray(
                    item.femaleStudents,
                    "Female Students"
                  )}
              </div>
              <div className="individualContent">
                {item.femaleLeaders[0] &&
                  this.createContentParagraphTextForArray(
                    item.femaleLeaders,
                    "Female Leaders"
                  )}
              </div>
              <div className="individualContent">
                {item.maleStudents[0] &&
                  this.createContentParagraphTextForArray(
                    item.maleStudents,
                    "Male Students"
                  )}
              </div>
              <div className="individualContent">
                {item.maleLeaders[0] &&
                  this.createContentParagraphTextForArray(
                    item.maleLeaders,
                    "Male Leaders"
                  )}
              </div>
            </div>
          )}
        </div>
      );
    });
  clickHandler = buttonId => {
    let buttons = this.state.buttons;
    buttons.forEach(button => {
      if (button.id === buttonId) {
        button.isHidden = !button.isHidden;
      }
    });
    this.setState({ buttons });
  };
  render() {
    return (
      <React.Fragment>{this.createButtonsForChurches(this.arr)}</React.Fragment>
    );
  }
}

ReactDOM.render(<App/>,  document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'/>