1

I'm looking for a way to dynamically render components based on the selected dropdown value. I'm using the ternary expression to check if it's equal to a static value now, but I'm wondering if it's possible, (If so, some direction would be much appreciated), to dynamically update the expression's value as well as the component rendered. Here is the code as it stands with being able to 'statically' render two components based on a static value.

componentDidMount() {

  axios.get('http://localhost:3000/api/groups')
   .then(response => {
     this.setState({ groups: response.data });
   })
   .catch(function (error) {
     console.log(error);
   });

}

  groupList() {
    if (this.state.groups instanceof Array) {
      return this.state.groups.map(function (groupsList, i) {
        return <ListGroupName group={groupsList} key={i} />;
      })
    }
  }


  handleChange = e => {
    this.setState({ selectedGroup: e.target.value });
  }

  /*** select element with options pulled from db via axios ***/
  <select
    value={this.state.selectedGroup}
    className="browser-default"
    onChange={this.handleChange}
  >
    <option disabled >Choose User Group</option>
    {this.groupList()}
  </select>


/* Is it possible to have "B&W Energy Services" be a dynamic value that changes as well 
as have the component be dynamically rendered if it matches the selected value? */

{this.state.selectedGroup === "B&W Energy Services" ? <BwEnergyServices /> : <Viachem />}
4
  • What do you mean by dynamically update the expression value? Are you talking about the ternary operater here? Commented Jun 3, 2020 at 21:27
  • Is it possible to dynamically update the part that says "B&W Energy Services" within the ternary expression? Sorry, trying to be specific here. Let me know if this still doesn't make sense. Commented Jun 3, 2020 at 21:47
  • I'll try to understand this further, so this dynamic value, on what basis do you want it to change? Right now, I think you just want to create an abstraction over this, but at the end of the day you'll still be using a switch or if statement to conditionally render different components. Commented Jun 3, 2020 at 22:13
  • I'd like it to change based on the selected value from the dropdown. It'll set the state of selectedGroup to the value of the option selected. (Reference the comment I made on the response below I think that represents what I'm trying to do) Commented Jun 3, 2020 at 22:19

1 Answer 1

1

(I hope i got the question right)

Since the value of the selected group isn't equal to the name of the component, you will need a sort of "factory-like" conversion. I mean you will need to match each value a Component to render. So you could use switch-case:

switch(this.state.selectedGroup){
        case "B&W Energy Services":
           return <BwEnergyServices />
        case "X":
           return <XComponent />
        case "Y":
           return <YComponent />
        default:
           return <Viachem />
}

EDIT

After reading your comments, I'll fix my answer:

Since JSX in react expects getting a react component, the only way to do it, is to map the options as keys to the components as called, and then render the component by selected key. Like this:

const components = {
    BwEnergyServices: BwEnergyServices, 
    Viachem: Viachem
    .
    .
    .
};

 const SelectedComponent = components[this.state.selectedGroup]; 
 {SelectedComponent ? <SelectedComponent /> : <DefaultComponent /> }
Sign up to request clarification or add additional context in comments.

7 Comments

So, part of my question is, is it possible to write the function in a way where I don't have to hardcode the switch statement? Basically, is this.state.selectedGroup === this.state.selectedGroup ? <Dynamic Component Here /> (I realize this might be a ridiculous statement, but I'm trying to see if it's at all possible)
This seems to be putting me in the right direction. After implementing this though I keep receiving the error of <BWEnergyServices /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements. for any component trying to be rendered.
It's not just for that one either. It occurs for any situation <Viachem /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.
Okay, this is working with a string but not with this.state.selectedGroup. It's returning an error of Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. If I do it with 'BwEnergyServices' it works. I suppose now I just need to ask how to set a state variable to a string.. Sounds simple, but I haven't found anything to help me yet.
Hi. As far as I know, React Component's names cannot include spaces. And since the keys should represent the Component names, I'm not sure it is possible.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.