Сверните каждую кнопку уникально, а не все сразу - PullRequest
0 голосов
/ 09 мая 2019

У меня есть тег <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 массивов есть члены как объекты, где бы они ни принадлежали

Я не знаю, как показать скрытый текст только для тех кнопок, на которые я нажимаю. Хотелось бы помочь.

1 Ответ

1 голос
/ 09 мая 2019

Вы должны создать массив для кнопок и задать свойство 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'/>
...