Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show hide multiple elements with react

Tags:

I want to use the same function showHide to show/hide each element within the parent. When I press the button all 3 blocks reacts and hide or show. How can I extend the function to work individualy for each div? This is a localhost test project so I can't provide any link unfortunately. Here you can see the final result

import React, { Component } from 'react';

class Homepage extends Component {  
    constructor( props ){
        super( props )
        this.state = {show : true};
        this.showHide = this.showHide.bind(this)
    }
    render() {
        return (    
            <section id="content">
                <div className="top-content">
                    <div className="container">
                        <h1>React</h1>
                        <h2>A JavaScript library for building user interfaces</h2>
                    </div>
                </div>
                <div className="container">
                    <div>
                        <div>
                            <h3>Declarative</h3>
                            <button onClick={this.showHide} className="button-primary btn">{this.changeName()}</button>
                            { this.state.show && 
                                <div>
                                    <p>text</p>
                                    <p>text</p>
                                </div>
                            }
                        </div>
                        <div>
                            <h3>Component-Based</h3>
                            <button onClick={this.showHide} className="button-primary btn">{this.changeName()}</button>
                            { this.state.show && 
                                <div>
                                    <p>text</p>
                                    <p>text</p>
                                </div>
                            }
                        </div>
                        <div>
                            <h3>Learn Once, Write Anywhere</h3>
                            <button onClick={this.showHide} className="button-primary btn">{this.changeName()}</button>
                            { this.state.show && 
                                <div>
                                    <p>text</p>
                                    <p>text</p>
                                </div>
                            }
                        </div>
                    </div>
                </div>
            </section>
      );  
    }
    changeName(){
        let text = "text "
        text += this.state.show === true ? "hide" : "show";
        return text;
    }
    showHide(){
        const { show } = this.state;
        this.setState( { show : !show})
    }
}
export default Homepage;
like image 991
Alex Avatar asked Jul 20 '18 07:07

Alex


1 Answers

The problem here is that your using the same state variable for each div (this.state.show).

If you want to have the divs behave differently, they each need their own state.

import React, { Component } from 'react';

class Homepage extends Component {  
    constructor( props ){
        super( props )
        this.state = {show: [true, true,true]};
    }
    render() {
        return (    
            <section id="content">
                <div className="top-content">
                    <div className="container">
                        <h1>React</h1>
                        <h2>A JavaScript library for building user interfaces</h2>
                    </div>
                </div>
                <div className="container">
                    <div>
                        <div>
                            <h3>Declarative</h3>
                            <button onClick={()->this.showHide(0)} className="button-primary btn">{this.changeName()}</button>
                            { this.state.show[0] && 
                                <div>
                                    <p>text</p>
                                    <p>text</p>
                                </div>
                            }
                        </div>
                        <div>
                            <h3>Component-Based</h3>
                            <button onClick={()->this.showHide(1)} className="button-primary btn">{this.changeName()}</button>
                            { this.state.show[1] && 
                                <div>
                                    <p>text</p>
                                    <p>text</p>
                                </div>
                            }
                        </div>
                        <div>
                            <h3>Learn Once, Write Anywhere</h3>
                            <button onClick={()->this.showHide(2)} className="button-primary btn">{this.changeName()}</button>
                            { this.state.show[2] && 
                                <div>
                                    <p>text</p>
                                    <p>text</p>
                                </div>
                            }
                        </div>
                    </div>
                </div>
            </section>
      );  
    }
    changeName(){
        let text = "text "
        text += this.state.show === true ? "hide" : "show";
        return text;
    }
    showHide(num){
        this.setState((prevState) => {
            const newItems = [...prevState.show];
            newItems[num] = !newItems[num];
            return {show: newItems};
        });
    }
}
export default Homepage;

Obviously there are nicer ways of doing this, but this is just an example to show the separation of states.

Can't test it right now, but shouldn't be far off.

UPDATE: @Lasitha ty for the much nicer edit!

like image 75
Jordan Mackie Avatar answered Oct 11 '22 18:10

Jordan Mackie