简体   繁体   中英

How can I show/hide elements with a specific class on click?

I'm fairly new to React and ES6, and I'm trying to develop the functionality so that when a button (.featureBtn) is clicked, a number of elements with a specific class (all.featureBtn elements) are hidden, and another component (Accessories) becomes visible.

Could this be done using state and a ternary statement, and if so how would this be done?

Please see my code below.

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;

since it is react, you no need to do with class like vanila js . You have the access to state, so can call it based on your current state.

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

so this showFirst and showSecond can return appropriate elements.

I would solve this by adding a state variable.Lets call it show. You can update show to hide when a button is clicked. Use this variable to conditionally change the classnames of the buttons you want to hide.

You can use the classnames npm package. for adding conditional classnames to the buttons you want to hide.

And use the ternary operator for Accessories. This same state variable can be used to show Accessories or hide it.

{ !this.state.show && <Accessories/>}

use ternary operator and one state variable, onClick on change state value.

{this.state.stateVariable? <>Component: null}

You could write a function that first gets the elements to be removed by class name, gets the buttons, and toggles display onClick.

See code

 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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM