2015-07-05 16 views
14

Tentativo di eseguire il rendering di componenti diversi in base agli argomenti passati con i dati. Se uso regolarmente o React.createElement (Item), funziona bene, ma tutte le altre opzioni falliscono.Creazione dinamica del componente

http://jsfiddle.net/zeen/fmhhtk5o/1/

var React = window.React; 

var data = {items: [ 
{ itemClass: 'Item', id: 1, contentsHTML: '', text: 'Item 1'}, 
{ itemClass: 'Item', id: 2, contentsHTML: '', text: 'Item 2'}, 
{ itemClass: 'Item', id: 3, contentsHTML: '', text: 'Item 3'}, 
{ itemClass: 'Item', id: 4, contentsHTML: '', text: 'Item 4'}, 
{ itemClass: 'Item', id: 5, contentsHTML: '', text: 'Item 5'} 
]}; 

var MyCatalog = React.createClass({ 
      getInitialState: function() { 
       return { data: { items: [] } }; 
      }, 

      componentDidMount: function() { 
       this.setState({ data: this.props.data }); 
      }, 

      render: function() { 
       return (
        <div className="catalog"> 
         HELLO!!! I AM A CATALOG!!! 

         <ItemList data={this.state.data}/> 
        </div> 
       ); 
      } 
     }); 

     var ItemList = React.createClass({ 
      render: function() { 
       console.log(this.props); 

var items = this.props.data["items"].map(function (itemData) { 

    var klass = itemData['itemClass'] || 'Item'; 
    var ItemFactory = React.createFactory(klass); 

//return <ItemFactory key={itemData['id']} data={itemData}/> // no 
//return <klass key={itemData['id']} data={itemData}/> // no 
//return React.createElement(klass, { key: itemData['id'], data: itemData }); // no 
//return <Item data={itemData}/> // ok 
//return React.createElement(Item, { data: itemData }); // ok 
//return React.createElement('Item', { key: itemData['id'], data: itemData }); // no 
//return React.createElement(React.createFactory('Item'), { data: itemData }); // no, error 
var component = Components['itemClass']; 
          return <component data={itemData} key={itemData['id']}/>  


       }); 
       console.log(items); 
       return (
React.createElement('div', { className: 'list' }, 
    React.createElement('div', null, 'And I am an ItemList :'), 
     React.createElement('div', null, 
      items 
     ) 
    ) 

        /*<div className="list"> 
         <div>And I am an ItemList :</div> 
         <div> 
          {items} 
         </div> 
        </div>*/ 
     ); 
      } 
     }); 

     var Item = window.Item = React.createClass({ 
      render: function() { 
       return (
        <div className="item"> 
         <div> 
          Regular item. Nothing special. 
         </div> 
         {this.props.children} 
        </div> 
       ); 
      } 
     }); 

     var Components = { 
      'Item': Item    
         }; 

     React.render( 
      <MyCatalog data={data}/>, 
      document.getElementById('app') 
     ); 

Come gestire questo caso per i diversi tipi di componenti?

+0

Quello che impedisce di utilizzare la notazione JSX nel vostro 'ItemList'? –

+0

Quando si dice "passato come dati" si intende come valore this.props. {PropertyName]? Perché non limitarsi a usare questo.proprio.children e passarli come nodi figli? Che dopotutto è una proprietà. O definire un numero di possibili tipi di componenti e quindi restituire una variabile che è un componente all'interno di una swicth –

+0

@ E_net4 come si può vedere ho usato anche JSX, ma non funziona – Dmytro

risposta

20

Questo dovrebbe funzionare:

var component = Components[itemData['itemClass']]); 
return React.createElement(component, { 
    data: itemData, 
    key: itemData['id'] 
}); 

Non è possibile utilizzare la sintassi JSX come questo <component .../> perché quando si ottiene transpiled component non si riferiscono a nulla.

UPDATE: Qui è il componente ITEMLIST aggiornato in piena:

var ItemList = React.createClass({ 
    render: function() { 
     console.log(this.props); 

     var items = this.props.data["items"].map(function(itemData) { 
      var component = Components[itemData['itemClass']]; 
      return React.createElement(component, { 
       data: itemData, 
       key: itemData['id'] 
      }); 
     }); 
     console.log(items); 
     return (
      <div className="list"> 
       <div>And I am an ItemList</div> 
       <div>{items}</div> 
      </div> 
     ); 
    } 
}); 

Lo si può vedere che lavorano in questo violino: http://jsfiddle.net/fmhhtk5o/3/

+0

dovrebbe funzionare? Ho provato questa variante, ma non funziona, puoi vedere il codice commentato che parte dalla riga 44 – Dmytro

+0

@Dmitry funziona bene, vedi l'aggiornamento. Penso che il tuo problema fosse che stavi usando 'Components ['itemClass']' invece di 'Components [itemData ['itemClass']]' – rojoca

+0

ora vedo il mio errore, grazie. – Dmytro

Problemi correlati