2015-07-05 9 views
14

Versuchen Sie, verschiedene Komponenten abhängig von den mit Daten übergebenen Argumenten zu rendern. Wenn ich reguläre oder React.createElement (Element) verwenden - es funktioniert gut, aber alle anderen Optionen fehlschlagen.Erstellen Sie dynamisch die Reaktionskomponente

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

Wie kann ich diesen Fall für verschiedene Arten von Komponenten zu verwalten?

+0

Was Sie verwenden JSX Notation in Ihrem 'ItemList' verhindert? –

+0

Wenn Sie "als Daten übergeben" sagen, meinen Sie das als Wert von this.props. {PropertyName]? Warum nicht einfach bei der Verwendung von this.props.children bleiben und sie als untergeordnete Knoten übergeben - was schließlich eine Eigenschaft ist. Oder definieren Sie eine Anzahl von möglichen Komponententypen und geben Sie dann eine Variable zurück, die eine Komponente innerhalb eines Switches –

+0

@ E_net4 ist, wie Sie sehen können Ich habe JSX auch verwendet, aber es funktioniert nicht – Dmytro

Antwort

20

sollte diese Arbeit:

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

Sie können Syntax nicht wie diese <component .../> verwenden JSX, weil, wenn es um etwas verweisen transpiled wird component nicht.

UPDATE: Hier ist die aktualisierte ItemList Komponente in voller Länge:

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

Sie können es in dieser Geige Arbeit sehen: http://jsfiddle.net/fmhhtk5o/3/

+0

sollte es funktionieren? Ich habe versucht, solche Variante, aber es funktioniert nicht, können Sie sehen, kommentierte Code beginnt ab Zeile 44 – Dmytro

+0

@Dmitry es funktioniert gut, siehe das Update. Ich glaube, Ihr Problem war, dass Sie 'Components ['itemClass']' anstelle von 'Components [itemData ['itemClass']]' – rojoca

+0

verwenden, jetzt sehe ich meinen Fehler, danke. – Dmytro