0

Hi I have a react app where I am returning several buttons. What I am trying to do is depending on the button you click another component will show and render in the view. I've looked at conditional rendering in the docs but I am not sure how to tie this to the state and render what I expect. Below is a sample of whats in the component.

// import all the components I need;

class FormContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
  dropdownVisible: false,
};
this.handleClick = this.handleClick.bind(this);

}

handleClick(event) {
if (!this.state.dropdownVisible) {
  document.addEventListener('click', this.handleOutsideClick, false);
} else {
  document.removeEventListener('click', this.handleOutsideClick, false);
}

this.setState(prevState => ({
  dropdownVisible: !prevState.dropdownVisible,
}));
}

handleOutsideClick(e) {
if (this.node.contains(e.target)) {
  return;
}
this.handleClick();
}

render() {
return (
  <form className="form-container">
    <h2>Browse The Database</h2>
    // here are the two buttons
    <button className="btn btn-default" onClick={this.handleClick}>
      By Fiscal Year
    </button>
    <button className="btn btn-default" onClick={this.handleClick}>
      By Research Organization
    </button>
    // depending on which one is clicked either of these table containers should render with the appropriate component passed in
    <div className="table-container">{this.state.dropdownVisible && <FiscalYearTable />}</div>
    <div className="table-container">
      {this.state.dropdownVisible && <ResearchOrganizationTable />}
    </div>
  </form>
);
}
}

export default FormContainer;

What is happening instead is that only one is rendering because I have not established the relationship between each button and the component I want to render. How can I establish this relationship using a conditional if or other method tied to the state?

3 Answers 3

1

Checkout the code below. I have added another state variable 'view' which gets the name of the view from the button being clicked and in the render checks the state value for which component to render

class FormContainer extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            dropdownVisible: false,
            view : ''
        };
    }

    handleClick = view => event => {
        if (!this.state.dropdownVisible) {
            document.addEventListener('click', this.handleOutsideClick, false);
        } else {
             document.removeEventListener('click', this.handleOutsideClick, false);
        }

        this.setState(prevState => ({
            dropdownVisible: !prevState.dropdownVisible,
            view
        }));
    }

    render() {
        return (
            <form className="form-container">
                <h2>Browse The Database</h2>
                <button className="btn btn-default" onClick={this.handleClick('view1')}>
                    By Fiscal Year
                </button>
                <button className="btn btn-default" onClick={this.handleClick('view2')}>
                    By Research Organization
                </button>

                <div className="table-container">
                    {this.state.view === 'view1' && <ResearchOrganizationTable />}
                </div>
            </form>
        );
    }
}
export default FormContainer;
Sign up to request clarification or add additional context in comments.

4 Comments

is there a typo with view in setState? what should its value be?
in es6 if the name of key and value are the same then it could be written as such.so instead of writting {name: name} you could write {name}
maybe missing {this.state.view === 'view2' && <FiscalYearTable />}
@LivingThing thanks for the explanation this is now working as expected, thanks again!
0

try a switch statement.

getView(view) {
  switch(view) {
  case: view1
    return ResearchOrganizationTable />

so each button could have an onClick event that passes the view you want to getView.

2 Comments

I dont think this is going to do it I'm going to have more than two buttons and rendered components when this is complete
How about creating a function that contains a switch statement for each component case. You could have view in your state and whenever you take some action of clicking on a button, you pass the view you want to the function and it returns the component.
0

What others suggested, is how I have done it before as well, switch statement, setting state based off button ID. Is this what your looking for:

import React, { Component } from 'react'


const ViewA = () => {
  return( <div>A VIEW</div>)
};
const ViewB = () => {
  return( <div>B VIEW</div>)
};
const ViewC = () => {
  return( <div>C VIEW</div>)
};
const ViewD = () => {
  return( <div>D VIEW</div>)
};


class App extends Component {
      constructor(props) {
        super(props);
        this.state = { 
          view: "A"
        };
     this.changeView=this.changeView.bind(this);   

  }

  changeView(e){
    console.log(e.target.id);
    this.setState({
      view: e.target.id
    })
  }

  renderButtons(){
    return (
      <div>
        <button id="A" onClick={this.changeView}>RENDER A</button>
        <button id="B" onClick={this.changeView}>RENDER B</button>
        <button id="C" onClick={this.changeView}>RENDER C</button>
        <button id="D" onClick={this.changeView}>RENDER D</button>
      </div>
    );
  }

  render() {
    const {view} = this.state;
    switch(view) {
      case "A":
      return(
        <div>
          {this.renderButtons()}
          <ViewA/>
        </div>
        )
      case "B":
      return(
        <div>
          {this.renderButtons()}
          <ViewB/>
        </div>
        )
      case "C":
      return(
        <div>
          {this.renderButtons()}
          <ViewC/>
        </div>
        )
      case "D":
      return(
        <div>
          {this.renderButtons()}
          <ViewD/>
        </div>
        )
    }

  }
}

export default App;

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.