0

I have multiple places in my React app where I have code like the below, just a large switch based on a format that will load the appropriate Component. Is there a way to dynamically create the component in React? Something similar to Reflection in Java, where I could do Class.instanceOf("Rule" + this.props.selectedFormatId");

renderRules() {
   switch (this.props.selectedFormatId) {
     case 1:
       return <Rules1 intl={this.props.intl} onRuleChange={this.props.onRuleChange}/>
     case 6:
       return <Rules6 intl={this.props.intl} onRuleChange={this.props.onRuleChange}/>
     case 7:
       return <Rules7 intl={this.props.intl} onRuleChange={this.props.onRuleChange}/>
       }
}

The ultimate goal is to just keep adding new Rules to the software without having to go into each of 5 places these switches appear and update them.

2
  • 1
    components are just functions, so you certainly can create them dynamically. you can also create a function which returns a class component Commented Jul 3, 2019 at 20:09
  • Possible duplicate of React / JSX Dynamic Component Name Commented Jul 3, 2019 at 20:14

2 Answers 2

2

Yes, it's absolutely possible. You can do something like this:

const dynamicComponents = {
  1: Rules1,
  2: Rules2,
  3: Rules3
}
const someValue = 1
const DynamicComponent = dynamicComponents[someValue]
return <DynamicComponent intl={this.props.intl} onRuleChange={this.props.onRuleChange} /> // This would be Rules1

This would render Rules1. This would mean that in order to add a new component you just need to add it to the dynamicComponents object. If you want to keep it even simpler, you could just have an array:

const dynamicComponents = [
  Rules1,
  Rules2,
  Rules3
]
const someValue = 2
const DynamicComponent = dynamicComponents[someValue]
return <DynamicComponent intl={this.props.intl} onRuleChange={this.props.onRuleChange} /> // this would be Rules2
Sign up to request clarification or add additional context in comments.

3 Comments

I would need to pass in the props too. Found in another answer, the solution is to cloneElement the response component and pass in the props then.
@bluedevil2k I've edited my answer to include props, the take on this is that basically you can build a component dynamically, after defining which component you're creating you can treat it as a standard component.
I went with adding the props in the React.createElement part rather in the "Hub" dynamic component. React.createElement(RuleHub.getRules(this.props.selectedFormatId), {intl: this.props.intl, onRuleChange:this.props.onRuleChange})
1

My method to solve similar issue is to save an object literal ("map") between key and component constructor, then given the key I have a reference to the Component.

const compMap = {
  key1: require('./Component1'),
  key2: require('./Component2'),
  key3: require('./Component3'),
};

// usage of the map
renderRules() {
  const Comp = compMap[this.props.selectedFormatId];
  return (<Comp prop1="prop1" />);
}

Comments

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.