Hareesh
Hareesh

Reputation: 1577

Dynamically rendering component from string: ReactJS

I was trying to call a component dynamically like this

var Tagname = 'Species';
options.push(<Tagname {...attrs}/>);

And im getting a warning in the console as

Warning: <Species /> is using uppercase HTML. Always use lowercase HTML tags in React.
Warning: The tag <Species> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.

All other codes are working fine. But this component does not working. How can i fix this?

Upvotes: 10

Views: 16709

Answers (2)

Muhammad Ahmar Khan
Muhammad Ahmar Khan

Reputation: 339

The following works for me...Just pass as full component tags from parent component and render in child component's jsx as normal variable.

Parent component:

export const ParentComponent = () => {
    const rows = [
      {component: <Comp1 />},
      {component: <Comp2 />},
    ]
    return ( <ChildComponent rows={rows} /> );
   }

Child component:

export const ChildComponent = ({rows}) => {
     return(
      <div>
          {rows.map((r)=>{
            return(
              r.component
            )
          })}
      </div>
     )
   }

Upvotes: -1

Mayank Shukla
Mayank Shukla

Reputation: 104369

Yes you can call the component dynamically, but it should be the component itself not the string.

Like this:

var Tagname = Species;    //component itself, not string
<Tagname {...attrs}/>;

Because JSX will get compiles into React.createElement(Component, props, ...children) and Component will be a string if it a html tag, otherwise a react component.

So if you pass React.createElement("Species", props, ...children), react will treat it as a html tag not a react component.

Update:

You can do one thing, create a map for each component, Like this:

const Map = {
  "componenet1": Component1,
  "componenet2": Component2
}

Now you can access the component using the string key, like this:

let name = "componenet1";
let Tagname = Map[name];
<Tagname {...attrs}/>;

Upvotes: 26

Related Questions