2015-03-22 2 views
9

Контекст: Я разрабатываю веб-приложение на основе виджета (например, несуществующий iGoogle, где пользователи могут выбирать, какие виджеты они хотят отображать). Каждый виджет является компонентом React.Render the React компонент, основанный на его имени

упрощенный пример: Вот 2 разные виджеты

var HelloWidget = React.createClass({ 
    render: function() { return <div>Hello {this.props.name}</div>; } 
}); 

var HiWidget = React.createClass({ 
    render: function() { return <div>Hi {this.props.name}</div>; } 
}); 

Как пользователь, я выбрал HiWidget и мое имя «чувак», поэтому, когда система получает свои предпочтения от инерционности слоя она выглядит это:

var dataFromDb = { 
    type: 'HiWidget', 
    name: 'dude' 
}; 

Как я могу визуализировать компонент React, когда у меня есть его имя в строке var?

Я попробовал это, основываясь на Dynamically Rendering a React component:

React.render(
    <dataFromDb.type name={dataFromDb.name} />, 
    document.getElementById('try2') 
); 

Он используется для работы с React 0.11, но не больше.

И я хотел бы избежать гигантского заявление переключателя:

switch (dataFromDb.type) { 
    case 'HiWidget': 
     var component = <HiWidget name={dataFromDb.name} />; 
     break; 
    case 'HelloWidget': 
     var component = <HelloWidget name={dataFromDb.name} />; 
     break; 
} 
React.render(
    component, 
    document.getElementById('try3') 
); 

JSFiddle со всем этим кодом здесь: http://jsfiddle.net/61xdfjk5/

ответ

14

Вы можете использовать объект в качестве поиска для типа компонента и держать детали рендеринга в одном месте:

var components = { 
    'HiWidget': HiWidget, 
    'HelloWidget': HelloWidget 
} 

var Component = components[dataFromObj.type] 
React.render(
    <Component name={dataFromObj.name}/>, 
    document.getElementById('try3') 
) 
3

JSX является подмножеством JavaScript, так что вы всегда можете использовать собственный синтаксис JavaScript внутри JS ИКС. Например, если классы ваших компонентов доступны в глобальном пространстве (window), вы можете сделать следующее:

React.render(
    React.createElement(window[dataFromDb.type], {name: dataFromDb.name}), 
    document.getElementById('try2') 
); 

JSFiddle here.

+0

Не понимаю, почему «окно [...]» необходимо здесь! Переменная dataFromDb находится в области видимости, поскольку 'dataFromDb.name' отлично работает, но если я удалю' window [...] ', это больше не работает. – al8anp

+0

@ al8anp Вам нужно 'window [...]', потому что таким образом вы получаете ссылку на класс, 'dataFromDb.name' - это просто строковое представление имени класса. 'React.createElement (...)' ожидает класс как первый аргумент – Vadim