React - Reference a component using a string
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.
reactjs
add a comment |
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.
reactjs
1
Why would you want to use a string instead of mapping the components references?
– Enmanuel Duran
Nov 16 '18 at 16:55
You'd need to load those components first, sounds like you're looking for dynamic import or require.
– Mrchief
Nov 16 '18 at 16:55
add a comment |
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.
reactjs
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.
reactjs
reactjs
asked Nov 16 '18 at 16:46
fractal5
70311129
70311129
1
Why would you want to use a string instead of mapping the components references?
– Enmanuel Duran
Nov 16 '18 at 16:55
You'd need to load those components first, sounds like you're looking for dynamic import or require.
– Mrchief
Nov 16 '18 at 16:55
add a comment |
1
Why would you want to use a string instead of mapping the components references?
– Enmanuel Duran
Nov 16 '18 at 16:55
You'd need to load those components first, sounds like you're looking for dynamic import or require.
– Mrchief
Nov 16 '18 at 16:55
1
1
Why would you want to use a string instead of mapping the components references?
– Enmanuel Duran
Nov 16 '18 at 16:55
Why would you want to use a string instead of mapping the components references?
– Enmanuel Duran
Nov 16 '18 at 16:55
You'd need to load those components first, sounds like you're looking for dynamic import or require.
– Mrchief
Nov 16 '18 at 16:55
You'd need to load those components first, sounds like you're looking for dynamic import or require.
– Mrchief
Nov 16 '18 at 16:55
add a comment |
3 Answers
3
active
oldest
votes
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>
Correct me if I'm wrong, but I think this is the same thing he's currently doing which is to map the objects properties to components, the only thing changing here is that we'd be accessing the mapped components differently. I do think it's a valid answer because you're clarifying that if it's a string it needs to be an HTML tag. Maybe it would be good to remark in your answer that this is not possible for custom components?
– Enmanuel Duran
Nov 16 '18 at 17:54
add a comment |
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"));
add a comment |
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.
I'm currently using a map, in an object. So I guess that's the best thing option at this time. Thanks for the response.
– fractal5
Nov 19 '18 at 15:11
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53342139%2freact-reference-a-component-using-a-string%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
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>
Correct me if I'm wrong, but I think this is the same thing he's currently doing which is to map the objects properties to components, the only thing changing here is that we'd be accessing the mapped components differently. I do think it's a valid answer because you're clarifying that if it's a string it needs to be an HTML tag. Maybe it would be good to remark in your answer that this is not possible for custom components?
– Enmanuel Duran
Nov 16 '18 at 17:54
add a comment |
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>
Correct me if I'm wrong, but I think this is the same thing he's currently doing which is to map the objects properties to components, the only thing changing here is that we'd be accessing the mapped components differently. I do think it's a valid answer because you're clarifying that if it's a string it needs to be an HTML tag. Maybe it would be good to remark in your answer that this is not possible for custom components?
– Enmanuel Duran
Nov 16 '18 at 17:54
add a comment |
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>
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>
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>
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>
answered Nov 16 '18 at 16:56
Tholle
33.8k53760
33.8k53760
Correct me if I'm wrong, but I think this is the same thing he's currently doing which is to map the objects properties to components, the only thing changing here is that we'd be accessing the mapped components differently. I do think it's a valid answer because you're clarifying that if it's a string it needs to be an HTML tag. Maybe it would be good to remark in your answer that this is not possible for custom components?
– Enmanuel Duran
Nov 16 '18 at 17:54
add a comment |
Correct me if I'm wrong, but I think this is the same thing he's currently doing which is to map the objects properties to components, the only thing changing here is that we'd be accessing the mapped components differently. I do think it's a valid answer because you're clarifying that if it's a string it needs to be an HTML tag. Maybe it would be good to remark in your answer that this is not possible for custom components?
– Enmanuel Duran
Nov 16 '18 at 17:54
Correct me if I'm wrong, but I think this is the same thing he's currently doing which is to map the objects properties to components, the only thing changing here is that we'd be accessing the mapped components differently. I do think it's a valid answer because you're clarifying that if it's a string it needs to be an HTML tag. Maybe it would be good to remark in your answer that this is not possible for custom components?
– Enmanuel Duran
Nov 16 '18 at 17:54
Correct me if I'm wrong, but I think this is the same thing he's currently doing which is to map the objects properties to components, the only thing changing here is that we'd be accessing the mapped components differently. I do think it's a valid answer because you're clarifying that if it's a string it needs to be an HTML tag. Maybe it would be good to remark in your answer that this is not possible for custom components?
– Enmanuel Duran
Nov 16 '18 at 17:54
add a comment |
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"));
add a comment |
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"));
add a comment |
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"));
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"));
answered Nov 16 '18 at 18:45
KornholioBeavis
866714
866714
add a comment |
add a comment |
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.
I'm currently using a map, in an object. So I guess that's the best thing option at this time. Thanks for the response.
– fractal5
Nov 19 '18 at 15:11
add a comment |
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.
I'm currently using a map, in an object. So I guess that's the best thing option at this time. Thanks for the response.
– fractal5
Nov 19 '18 at 15:11
add a comment |
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.
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.
edited Nov 16 '18 at 20:23
answered Nov 16 '18 at 20:14
estus
67.2k2198213
67.2k2198213
I'm currently using a map, in an object. So I guess that's the best thing option at this time. Thanks for the response.
– fractal5
Nov 19 '18 at 15:11
add a comment |
I'm currently using a map, in an object. So I guess that's the best thing option at this time. Thanks for the response.
– fractal5
Nov 19 '18 at 15:11
I'm currently using a map, in an object. So I guess that's the best thing option at this time. Thanks for the response.
– fractal5
Nov 19 '18 at 15:11
I'm currently using a map, in an object. So I guess that's the best thing option at this time. Thanks for the response.
– fractal5
Nov 19 '18 at 15:11
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53342139%2freact-reference-a-component-using-a-string%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Why would you want to use a string instead of mapping the components references?
– Enmanuel Duran
Nov 16 '18 at 16:55
You'd need to load those components first, sounds like you're looking for dynamic import or require.
– Mrchief
Nov 16 '18 at 16:55