Geetanjali Panda
Geetanjali Panda

Reputation: 73

How to render a react component from a string name

I want to dynamically render a react component from its string-name. Here is what I have done, but it does not work. Can this be done ? An example would really help.

string_name is the name of the component.

var MyComponent = React.createElement(window[string_name], {});
return (
      <div className="wrapper">
          <div>Hello World</div>
          <MyComponent/>
      </div>
    )

Upvotes: 5

Views: 10563

Answers (2)

govgo
govgo

Reputation: 635

One thing you can do is require a child component within MyComponent and render it in your return. Write your custom function to render the component dynamically in the Child, then require it in MyComponent.

var React = require('react');

var Names = React.createClass({
  render: function(){

    // Map the names and loop through
    var names = this.props.names.map(function(name, index){

        return(
            <div> 
                <li className="list-group-item" key={index}>
                  {<h4>{name[index]}</h4>}

                </li>
            </div>
        )
    });
  }
});

/*We then export the Names component*/
module.exports = Names;

Below is the Parent component.

var React = require('react');
var Names = require('./Names');

var MyComponent = React.createClass({
/*This will set the initial state for any state the component handles. usually empty data*/
 getInitialState: function(){
    return {

       names: ["My Component", "Your Component"]

    }
 },


 render: function(){

    return(

        <div className="row">

            <div className="col-md-4">

                <Names names={this.state.names} />

            </div>

        </div>
    );
 }
});

Upvotes: 0

Chris
Chris

Reputation: 58182

The key bit missing, and I don't know if it's documented anywhere, but you need to use a capital letter for the JSX compiler (?) to recoginise it as a type.

import AllComponents from 'Components';

const FooType = 'Foo';

return (
    <div className="wrapper">
        <div>Hello World</div>
        <AllComponents[FooType] />
    </div>
);

Edit - As per the comments

class Foo extends React.Component {
    render() { 
        return <div>Foo 123</div>; 
    }
};

class Bar extends React.Component {
    render() { 
        return <div>Bar 123</div>; 
    }
};


class App extends React.Component {


  render() {
    const all = {
        'Foo': Foo,
        'Bar': Bar,    
    };

    // For the sake of the demo, just randomly pick one of the two
    // usually this would come from an import, or something similar
    const randomKey = ['Foo', 'Bar'][Math.floor(Math.random() * 2)];

    // The resolved component must begin with a capital letter
    const Type = all[randomKey];


    return (
        <div>
            <Type />
        </div>    
    );
  }

};


ReactDOM.render(<App />, document.getElementById('root')); 

JSBin: http://jsbin.com/noluyu/5/edit?js,output

Edit 2

Our typical apps that render components dynamically, usually have an index.js file at the root of all the components directory, that simple list all possible components:

// index.js
export Breadcrumb                from './breadcrumb/Breadcrumb';
export Checkbox                  from './checkbox/Checkbox';
export Comment                   from './comment/Comment';

Then all you have to do is something like:

import AllComponents from './index.js';

const myType = 'Checkbox';
const Type = AllComponents[myType];

.. later ..
return <div><Type /></div>;

Upvotes: 8

Related Questions