Как я могу показать / скрыть элементы с указанным классом c при клике? - PullRequest
0 голосов
/ 30 апреля 2020

Я довольно новичок в React и ES6, и я пытаюсь развить функциональность так, чтобы при нажатии кнопки (.featureBtn) количество элементов с указанным c классом (все элементы .featureBtn) ) скрыты, и другой компонент (Аксессуары) становится видимым.

Может ли это быть сделано с использованием состояния и троичного оператора, и если да, то как это будет сделано?

См. мой код ниже .

class ProductView extends React.Component {

  static contextType = ChoicesContext;

  constructor(props) {
    super(props);

    this.forwardSequence = this.forwardSequence.bind(this);
    this.reverseSequence = this.reverseSequence.bind(this);
  }

  static sequenceImages(folder, filename, type) {
    let images = [];
    for (let i = 0; i < 51; i++) {
      images.push(<img src={require(`../images/sequences/${folder}/${filename}_000${i}.jpg`)} alt="" className={`${type} sequenceImage`} />);
    }
    return images;
  }

  async sleep(ms) {
    return new Promise(r => setTimeout(r, ms))
  }

  async forwardSequence(sequence, effect) {
    Array.prototype.reduce.call
      ( sequence
      , (r, img) => r.then(_ => this.sleep(50)).then(_ => effect(img))
      , Promise.resolve()
      )
  }

  async reverseSequence(sequence, effect) {
    Array.prototype.reduceRight.call
      ( sequence
      , (r, img) => r.then(_ => this.sleep(50)).then(_ => effect(img))
      , Promise.resolve()
      )
  }

  render() {
    const etseq = document.getElementsByClassName("exploreTech");
    const uiseq = document.getElementsByClassName("userInterface");

    const { choices } = this.context;
    const CurrentProduct = ProductData.filter(x => x.name === choices.productSelected);

    return (
      <>

        <div className="productInteractive wrapper">
          {CurrentProduct.map((item, i) => (
            <main className={item.slug}>

              <div key={i} className="imageSequence">
                <img src={require(`../images/sequences/${item.static_img}`)} alt="" className="staticImage" />
                {ProductView.sequenceImages(item.explore_tech_img_folder, item.explore_tech_filename, "exploreTech")}
                {ProductView.sequenceImages(item.user_interface_img_folder, item.user_interface_filename, "userInterface")}
              </div>

             {/* When one of the two buttons below are clicked, they should both hide (presumably using the featureBtn class), and the <Accessories /> component should become visible. */}

              <button
                onClick={() => this.forwardSequence(etseq, img => img.style.opacity = 1)}
                className="btn featureBtn userInterfaceBtn"
              >User Interface</button>

              <button
                onClick={() => this.forwardSequence(uiseq, img => img.style.opacity = 1)}
                className="btn-reverse featureBtn exploreTechnologiesBtn"
              >Explore Technologies</button>

           <Accessories />

            </main>
          ))}
        </div>
      </>
    );
  }
}
export default ProductView;

Ответы [ 4 ]

1 голос
/ 30 апреля 2020

, поскольку это реакция, вам не нужно делать с class как vanila js. У вас есть доступ к состоянию, поэтому вы можете вызывать его в зависимости от вашего текущего состояния.

if(this.state.showFirst) {
  this.showFirst();
} else {
  this.showSecond();
}

, чтобы showFirst and showSecond мог вернуть соответствующие элементы.

0 голосов
/ 30 апреля 2020

использовать троичный оператор и одну переменную состояния, onClick при изменении значения состояния.

{this.state.stateVariable? <> Компонент: ноль}

0 голосов
/ 30 апреля 2020

Вы можете написать функцию, которая сначала получает элементы, которые будут удалены по имени класса, получает кнопки и переключает отображение onClick.

См. Код

class ProductView extends React.Component {

  static contextType = ChoicesContext;

  constructor(props) {
    super(props);

    this.forwardSequence = this.forwardSequence.bind(this);
    this.reverseSequence = this.reverseSequence.bind(this);
  }

  static sequenceImages(folder, filename, type) {
    let images = [];
    for (let i = 0; i < 51; i++) {
      images.push(<img src={require(`../images/sequences/${folder}/${filename}_000${i}.jpg`)} alt="" className={`${type} sequenceImage`} />);
    }
    return images;
  }

  async sleep(ms) {
    return new Promise(r => setTimeout(r, ms))
  }

  async forwardSequence(sequence, effect) {
    Array.prototype.reduce.call
      ( sequence
      , (r, img) => r.then(_ => this.sleep(50)).then(_ => effect(img))
      , Promise.resolve()
      )
  }

  async reverseSequence(sequence, effect) {
    Array.prototype.reduceRight.call
      ( sequence
      , (r, img) => r.then(_ => this.sleep(50)).then(_ => effect(img))
      , Promise.resolve()
      )
  }
      //function to hide elements with classname .featureBtn. 
  toggleDisplay(){
      const elementsToBeRemoved= document.getElementsByClassName('featureBtn');
      const button = document.getElementsByTagName('button'); //if it is a specific button, give the button an ID and use getElementById
      if(elementsToBeRemoved){
       elementsToBeRemoved.styles.display('none')
       //insert the other component to be shown 
      } else{
       elementsToBeRemoved.styles.display('inline')
       //hide the other component
      }
      //attach this function on the onClick property and see what happens.

  }
  
  render() {
    const etseq = document.getElementsByClassName("exploreTech");
    const uiseq = document.getElementsByClassName("userInterface");

    const { choices } = this.context;
    const CurrentProduct = ProductData.filter(x => x.name === choices.productSelected);

    return (
      <>

        <div className="productInteractive wrapper">
          {CurrentProduct.map((item, i) => (
            <main className={item.slug}>

              <div key={i} className="imageSequence">
                <img src={require(`../images/sequences/${item.static_img}`)} alt="" className="staticImage" />
                {ProductView.sequenceImages(item.explore_tech_img_folder, item.explore_tech_filename, "exploreTech")}
                {ProductView.sequenceImages(item.user_interface_img_folder, item.user_interface_filename, "userInterface")}
              </div>

             {/* When one of the two buttons below are clicked, they should both hide (presumably using the featureBtn class), and the <Accessories /> component should become visible. */}

              <button
                onClick={() => this.forwardSequence(etseq, img => img.style.opacity = 1)}
                className="btn featureBtn userInterfaceBtn"
              >User Interface</button>

              <button
                onClick={() => this.forwardSequence(uiseq, img => img.style.opacity = 1)}
                className="btn-reverse featureBtn exploreTechnologiesBtn"
              >Explore Technologies</button>

           <Accessories />

            </main>
          ))}
        </div>
      </>
    );
  }
}
export default ProductView;
0 голосов
/ 30 апреля 2020

Я бы решил эту проблему, добавив переменную состояния. Пусть она называется show. Вы можете обновить шоу, чтобы скрыть при нажатии кнопки. Используйте эту переменную для условного изменения имен классов кнопок, которые вы хотите скрыть.

Вы можете использовать пакет classnames npm. для добавления условных имен классов к кнопкам, которые вы хотите скрыть.

И используйте троичный оператор для аксессуаров. Эту же переменную состояния можно использовать, чтобы показать аксессуары или скрыть ее.

{ !this.state.show && <Accessories/>}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...