JavaHava
JavaHava

Reputation: 189

How to conditionally render and hide multiple components onClick in JSX?

My Class Component houses 4 different buttons. Ideally when the user presses one of those buttons an Accordion Element corresponding to that button should render. Like if someone presses the summary button the summaryAccordion will render etc.

The problem is I don't know how to render only that component based on the button click.

If the user presses the summary button the summaryAccordion will render, but if the user presses the rates button after the summary button, the summary accordion should hide itself then the ratesAccordion should render. This same logic should be carried to all four buttons.

Below is my attempt at solving this:

class TabMenuButtons extends Component {
    constructor(props) {
        super(props);
        this.state = {
            rendersummaryAccordions: false,
            renderservicesAccordions: false,
            rendertravelAccordions: false, 
            renderratesAccordions: false, 

            isSummaryAccordionActive: false, 
            isServicesAccordionActive: false, 
            isTravelAccordionActive: false, 
            isRatesAccordionActive: false, 


        };


    }

        // The Summary Button onClick calls this function to set the state of the summaryAccordionDetector variable
        setStateifSummaryAccordionsActive = () => {
            this.setState({isSummaryAccordionActive: true})
            console.log(this.state.isSummaryAccordionActive)
            this.callSummaryAccordionsLogicGate();
            console.log("setStateisSummaryAccordionsActive Was called")
        }

        //Then the function above  calls this function that checks if the summaryAccordionDetector variable is really true 
        callSummaryAccordionsLogicGate = () => {
            if (this.state.isSummaryAccordionActive) {
                console.log("callSummaryAccordionsLogicGate found that theSummaryAccordion is active")
               this.summaryAccordionsLogicGate();

            }
            else {
                console.log("callSummaryAccordionsLogicGate found that the summary accordion wasn't active")
            }
        }

        //If the function above verifies that the summaryAccordionDetector is really true it calls this function which renders the summary accordion
           summaryAccordionsLogicGate = () => {
                this.setState({rendersummaryAccordions: true});
                console.log("summaryAccordionsLogicGate was called, render the summary accordion")
        } 


        // The Services onClick calls this function to set the state of the servicesAccordionDetector variable
        setStateifServicesAccordionsActive = () => {
            this.setState({isServicesAccordionActive: true})
            console.log(this.state.isServicesAccordionActive)
            this.callServicesAccordionsLogicGate();
            console.log("setStateisServicesAccordionsActive Was called")
        }

        //Then the function above  calls this function that checks if the summaryAccordionDetector variable is really true 
        callServicesAccordionsLogicGate = () => {
            if (this.state.isServicesAccordionActive) {
                console.log("callServicesAccordionsLogicGate found that theSummaryAccordion is active")
               this.servicesAccordionsLogicGate();

            }
            else {
                console.log("callServicesAccordionsLogicGate found that the summary accordion wasn't active")
            }
        }

        //If the function above verifies that the summaryAccordionDetector is really true it calls this function which renders the summary accordion
        servicesAccordionsLogicGate = () => {
            this.setState({renderservicesAccordions: true});
            console.log("servicesAccordionsLogicGate was called, render the services accordion")
    } 



        render() {
//PlaceHolder Variables for the Accordions
            let summaryAccordionPlaceHolder = null
            let servicesAccordionPlaceHolder = null
            let ratesAccordionPlaceHolder = null
            let travelAccordionPlaceHolder = null

//If renderSummaryAccordions is true and renderServicesAccordions is false then set a variable equal to the summaryAccordion Element so that it can render
            this.state.rendersummaryAccordions && this.state.renderservicesAccordions === false ? summaryAccordionPlaceHolder = <SummaryAccordions/> : summaryAccordionPlaceHolder = null;
            this.state.renderservicesAccordions && this.state.rendersummaryAccordions === false ? servicesAccordionPlaceHolder = <ServicesAccordions/> : servicesAccordionPlaceHolder = null;


            return (
                <div>
                    <center>
                        <table cellspacing="30px">
                            <tr>
                                <td>
                                    <Button label="SUMMARY" icon="pi pi-home" className="TabMenuButtons" onClick={this.setStateifSummaryAccordionsActive} style={{ marginRight: '.25em', borderRadius: '8%', backgroundColor: "#1c479c" }}></Button>
                                </td>
                                <td>
                                    <Button label="SERVICES" icon="pi pi-users" className="TabMenuButtons" onClick={this.setStateifServicesAccordionsActive} style={{ marginRight: '.25em', borderRadius: '8%', backgroundColor: "#1c479c" }}></Button>
                                </td>
                                <td>
                                    <Button label="TRAVEL" icon="pi pi-cloud" className="TabMenuButtons"  style={{ marginRight: '.25em', borderRadius: '8%', backgroundColor: "#1c479c" }}></Button>
                                </td>
                                <td>
                                    <Button label="RATES" icon="pi pi-money-bill" className="TabMenuButtons" style={{ marginRight: '.25em', borderRadius: '8%', backgroundColor: "#1c479c" }}></Button>
                                </td>
                            </tr>
                        </table>
                    </center>
                    <tr>

                        {/* EDIT THIS to become dynamic */}
                        <td className="StaticTextBelowTabView"><h1>  ITEM: <em>$67,000.00 </em></h1> </td>
                        <td className="StaticTextBelowTabView"><h1> ITEM: <em>$5,000.00</em>  </h1></td>
                        <td className="StaticTextBelowTabView"><h1> ITEM: <em>$54,406.00</em> </h1></td>
                        <td className="StaticTextBelowTabView"><h1>  ITEM: <em>1,000</em> </h1></td>
                        <td className="StaticTextBelowTabView"><h1> ITEM: <em>20.00%</em></h1></td>
                    </tr>
                    <br />
{/* Render the placeHolder Elements here */}
                {ratesAccordionPlaceHolder}
                {servicesAccordionPlaceHolder}
                {travelAccordionPlaceHolder}
                {summaryAccordionPlaceHolder}
                </div>
            );
        }

    }

I am new to React any help is appreciated

EDIT 1:

class TabMenuButtons extends Component {
    constructor(props) {
        super(props);
        this.state = {
        renderSummaryAccordion: false,
        renderServicesAccordion: false,
        renderTravelAccordion: false, 
        renderRatesAccordion: false

        };


    }





        render() {


            return (
                <div>
                    <center>
                        <table cellspacing="30px">
                            <tr>
                                <td>
                                    <Button label="SUMMARY" icon="pi pi-home" className="TabMenuButtons" onClick={()=> this.setState({renderSummaryAccordion : !this.state.renderSummaryAccordion})} style={{ marginRight: '.25em', borderRadius: '8%', backgroundColor: "#1c479c" }}></Button>
                                </td>
                                <td>
                                    <Button label="SERVICES" icon="pi pi-users" className="TabMenuButtons" onClick={()=> this.setState({renderServicesAccordion : !this.state.renderServicesAccordion})} style={{ marginRight: '.25em', borderRadius: '8%', backgroundColor: "#1c479c" }}></Button>
                                </td>
                                <td>
                                    <Button label="TRAVEL" icon="pi pi-cloud" className="TabMenuButtons"  style={{ marginRight: '.25em', borderRadius: '8%', backgroundColor: "#1c479c" }}></Button>
                                </td>
                                <td>
                                    <Button label="RATES" icon="pi pi-money-bill" className="TabMenuButtons" style={{ marginRight: '.25em', borderRadius: '8%', backgroundColor: "#1c479c" }}></Button>
                                </td>
                            </tr>
                        </table>
                    </center>
                    <tr>

                        {/* EDIT THIS to become dynamic */}
                        <td className="StaticTextBelowTabView"><h1>  ITEM: <em>$67,000.00 </em></h1> </td>
                        <td className="StaticTextBelowTabView"><h1> ITEM: <em>$5,000.00</em>  </h1></td>
                        <td className="StaticTextBelowTabView"><h1> ITEM: <em>$54,406.00</em> </h1></td>
                        <td className="StaticTextBelowTabView"><h1>  ITEM: <em>1,000</em> </h1></td>
                        <td className="StaticTextBelowTabView"><h1> ITEM: <em>20.00%</em></h1></td>
                    </tr>
                    <br />
{this.state.renderSummaryAccordion && <SummaryAccordions/>}
{this.state.renderServicesAccordion && <ServicesAccordions/>}
                </div>
            );
        }

    }

Upvotes: 1

Views: 932

Answers (1)

Dupocas
Dupocas

Reputation: 21297

You just need to bind the button click to a state's property (usually a boolean) and use conditional render to render only those components that should be displayed:

render(){
    return (
        <>
            <button onClick={() => this.setState({condition1 : !this.state.condition1})}> Toggle BUtton 1 </button>
            <tr>
                 {condition1 && <td>foo</td>}
                 {condition2 && <td>foo</td>}
            </tr>
        </>
    )
}

Upvotes: 1

Related Questions