Как сделать компонент реагирования из имени строки

Я хочу динамически визуализировать компонент реагирования по его строковому имени. Вот что я сделал, но это не работает. Можно ли это сделать? Пример действительно помог бы.

имя_строки это имя компонента.

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

2 ответа

Решение

Бит ключа отсутствует, и я не знаю, документирован ли он где-либо, но вам нужно использовать заглавную букву для компилятора JSX (?), Чтобы распознать его как тип.

import AllComponents from 'Components';

const FooType = 'Foo';

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

Редактировать - согласно комментариям

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

Редактировать 2

Наши типичные приложения, которые визуализируют компоненты динамически, обычно имеют файл index.js в корне каталога всех компонентов, в котором просто перечислены все возможные компоненты:

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

Тогда все, что вам нужно сделать, это что-то вроде:

import AllComponents from './index.js';

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

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

Одна вещь, которую вы можете сделать, это потребовать дочерний компонент в MyComponent и отобразить его в вашем возвращении. Напишите свою пользовательскую функцию для динамического рендеринга компонента в Child, а затем потребуйте его в 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;

Ниже представлен родительский компонент.

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>
    );
 }
});
Другие вопросы по тегам