【问题标题】:Collapse each button uniquely, instead of all at once唯一地折叠每个按钮,而不是一次全部折叠
【发布时间】:2019-09-27 12:01:07
【问题描述】:

我有一个<div> 标记,其中包含不同数量的按钮。单击每个按钮时,我都会显示一个反应变量。我的问题是,每当我单击任何按钮时,都会显示每个隐藏的文本;但是我只希望按钮在单击它们时显示它们的隐藏文本,以便它们的行为独特。

我已经尝试了一些条件渲染的想法,但我不确定如何正确地攻击它。

我有一个为每个教堂创建按钮的函数。这是那个函数:

  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 个数组中的每一个中,无论他们属于哪里,都有成员作为对象

我不知道如何只显示我单击的按钮的隐藏文本。希望得到一些帮助。

【问题讨论】:

  • 在上面的问题中粘贴arr数组,因为没有arr就很难理解。
  • arr 描述已添加
  • 你可以尝试使用 refs 来解决这个问题:reactjs.org/docs/refs-and-the-dom.html
  • @rowlandev 刚刚添加了一个可行的解决方案,我希望它能解决问题。请检查。

标签: reactjs button event-handling state collapsable


【解决方案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'/>

【讨论】:

  • 你的回答激发了我的答案,谢谢 - 我决定让每个教堂按钮成为一个组件,然后每个按钮都有自己的状态,其中包含“on”布尔值。非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-21
  • 2019-03-02
  • 1970-01-01
  • 2019-10-29
  • 2016-08-20
  • 2015-04-07
  • 2018-12-24
相关资源
最近更新 更多