Reputation: 94319
Suppose I have:
import MyComponent from "../somewhere"
I can create an instance of it by doing:
<MyComponent myprops={myprops} />
But can I create one programmatically from MyComponent
and add props?
For example, I have a list of component references:
import comp1 from "somewhere"
import comp2 from "somewhere"
import comp3 from "somewhere"
var myComponents = [
comp1, comp2, comp3
];
And now I have to take one of them and put in the view:
var randomComponent = myComponents[Math.random() * 3 | 0];
// render
render(){
return randomComponent; // this doesn't work and certain props have to be added
}
Is there a way to avoid doing the following and achieve the same?
var myComponents = [
<comp1 props=... />, <comp2 props=... />, <comp3 props=... />
];
Upvotes: 3
Views: 130
Reputation: 2627
Thought I would share. I had a very specific use case for this using imported svg files, but I believe this would work with components as well. I wanted to have a button component that would load different svg icons given a prop type.
import LightBulb from '../my-icons/Lightbulb.svg';
const ICON_TYPES = {
LightBulb: 'LightBulb',
};
const ICON_TYPE_FILES = {
[ICON_TYPES.LightBulb]: LightBulb,
};
export default function IconButton({iconType}) {
const IconComponent = ICON_TYPE_FILES[iconType];
return (
<Icon>
<IconComponent />
</Icon>
);
};
IconButton.ICON_TYPES = ICON_TYPES
Using component:
<IconButton
iconType={IconButton.ICON_TYPES.LightBulb}
/>
Upvotes: 0
Reputation: 57964
You can do the following:
var RandomComponent = myComponents[Math.random() * 3 | 0];
render() {
return <RandomComponent props={foobar} />;
}
The above is demonstrated at the React Docs where the following is mentioned:
You cannot use a general expression as the React element type. If you do want to use a general expression to indicate the type of the element, just assign it to a capitalized variable first. (emphasis mine)
The reason why the component's name must be capitalized is because it will be treated as a built-in component (DOM component) if not. This works because it's just transpiled into this:
React.createElement(RandomComponent, { props: foobar });
And RandomComponent
still refers to a random selected component. If randomComponent
is not capitalized, you can just do it without JSX like so:
React.createElement(randomComponent, { props: foobar });
You just won't be able to do it with JSX because randomComponent
is lowercase and will incidentally be transpiled into this:
React.createElement("randomComponent", { props: foobar });
Which is problematic as "randomComponent"
does not refer to randomComponent
.
Upvotes: 4
Reputation: 32402
see Create react component dynamically
var component = myComponents[Math.random()*3 |0];
return React.createElement(component, props);
Upvotes: 2