Reputation: 2132
I need to call a component by using a string that is the same as the component name.
Is there a way to do this without using switch or mapping the strings to the components, which I am able to do currently.
I tried this, but it doesn't work, although this article uses a similar approach.
render() {
let CompName = 'SelectComponent';
return <CompName />
}
This is just an example. The strings (component names) will be defined in an config file, which holds properties for several input fields that need to be rendered.
Thanks.
Upvotes: 1
Views: 2022
Reputation: 222840
Is there a way to do this without using switch or mapping the strings to the components
There is no way because the framework doesn't have a way to associate component function names with components.
There should be a map that maps components to their names, e.g.:
import Foo from './Foo';
import Bar from './Bar';
const componentsMap = { Foo, Bar };
...
let CompName = 'Foo';
return <componentsMap[CompName] />
The workflow can be improved with a decorator, especially for class components:
const componentsMap = {};
const mapComponent = name => Comp => {
name = name || Comp.displayName;
if (!name)
throw new Error('no comp name');
return componentsMap[name] = Comp;
}
...
@mapComponent()
class Foo extends Component {
static displayName = 'Foo';
...
}
const Bar = mapComponent('Bar')(props => ...);
Component name can be moved to static property like displayName
but cannot be avoided because function name
property is mangled during minification and cannot be relied on.
Upvotes: 0
Reputation: 2442
I think the closest you can get to is calling an object property via string
const Component1 = ()=><h1>This is component 1</h1>
const Component2 = () => <h1>This is component 2</h1>
const obj = {
component1: <Component1 />,
component2: <Component2 />
}
render(obj["component2"], document.getElementById("app"));
Upvotes: 0
Reputation: 112867
You can use strings for built-in elements (div
, span
, ...) but if you want to use a custom component, you need a reference to the component variable.
You can put all your components in an object and get the component variable with the help of the component name.
Example
function Foo() {
return <div> Foo </div>;
}
function Bar() {
return <div> Bar </div>;
}
const components = { Foo, Bar };
function App(props) {
const { regularTag: RegularTag, componentTag } = props;
const Component = components[componentTag];
return (
<div>
<Component />
<RegularTag> Baz </RegularTag>
</div>
);
}
ReactDOM.render(
<App componentTag={"Foo"} regularTag={"div"} />,
document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Upvotes: 1