2015-03-22 5 views
9

Contesto: Sto sviluppando una webapp basata su widget, (come la defunta iGoogle, in cui gli utenti possono scegliere quali widget si desidera visualizzare). Ogni widget è un componente React.Rendering di un componente React in base al suo nome

esempio semplificato: Qui ci sono 2 i widget diversi

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

Come utente, ho scelto il HiWidget e il mio nome è "dude" in modo che quando il sistema riceve le mie preferenze dal strato di persistenza sembra questo:

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

Come posso rendere un componente di reagire quando ho il suo nome in un var stringa?

Ho provato questo, sulla base di Dynamically Rendering a React component:

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

è abituato a lavorare con Reagire 0,11, ma non più.

E vorrei evitare di avere un'istruzione switch gigante:

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 con tutto questo codice qui: http://jsfiddle.net/61xdfjk5/

risposta

14

Si potrebbe usare un oggetto come una ricerca per il tipo di componente e mantenere la dettagli di rendendolo in un unico luogo:

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

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

JSX è un superset di JavaScript, in modo da poter sempre utilizzare la sintassi nativa JavaScript all'interno di JS X. Per esempio, se sono disponibili nello spazio globale (window) classi di componenti, è possibile effettuare le seguenti operazioni:

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

JSFiddle here.

+0

Non capisco perché 'window [...]' è necessario qui! La variabile dataFromDb è in ambito dato che 'dataFromDb.name' funziona bene ma se rimuovo' window [...] 'non funziona più. – al8anp

+0

@ al8anp È necessario 'window [...]' perché in questo modo si ottiene il riferimento alla classe, 'dataFromDb.name' è solo una rappresentazione in stringa del nome della classe. 'React.createElement (...)' si aspetta la classe come primo argomento – Vadim