5

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;
2
  • Please format your question.
    – ChrisR
    Commented Jul 20, 2018 at 8:12
  • When updating state using the previous state, you should do so like this: this.setState(prevState => ({show : !prevState.show})) Commented Jul 20, 2018 at 8:44

1 Answer 1

4

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!

5
  • 1
    Thanks, that will do the job!
    – Alex
    Commented Jul 20, 2018 at 8:54
  • @Alex no problem! If you want to go down an even more react-y route, you could make each of these divs into their components that handle their own state, rather than this parent component (Homepage) handling the state for all 3 :) Commented Jul 20, 2018 at 8:56
  • 1
    sounds even more great, I think I didn't figure this out before because is my third day of react... :)
    – Alex
    Commented Jul 20, 2018 at 9:00
  • @Alex keep going with it! It'll pay off for sure. Commented Jul 20, 2018 at 9:03
  • 1
    Thanks a lot, great day!
    – Alex
    Commented Jul 20, 2018 at 9:09

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.