React - Reference a component using a string












0














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.










share|improve this question


















  • 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
















0














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.










share|improve this question


















  • 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














0












0








0







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.










share|improve this question













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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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














  • 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












3 Answers
3






active

oldest

votes


















1














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>








share|improve this answer





















  • 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





















0














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"));





share|improve this answer





























    0















    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.






    share|improve this answer























    • 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











    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    1














    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>








    share|improve this answer





















    • 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


















    1














    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>








    share|improve this answer





















    • 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
















    1












    1








    1






    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>








    share|improve this answer












    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>






    share|improve this answer












    share|improve this answer



    share|improve this answer










    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




















    • 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















    0














    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"));





    share|improve this answer


























      0














      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"));





      share|improve this answer
























        0












        0








        0






        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"));





        share|improve this answer












        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"));






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 16 '18 at 18:45









        KornholioBeavis

        866714




        866714























            0















            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.






            share|improve this answer























            • 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
















            0















            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.






            share|improve this answer























            • 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














            0












            0








            0







            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.






            share|improve this answer















            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.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            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


















            • 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


















            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            How to change which sound is reproduced for terminal bell?

            Can I use Tabulator js library in my java Spring + Thymeleaf project?

            Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents