Trying to render different components depending on arguments passed with data. If I use regular or React.createElement(Item) - it works fine, but all other options fail.
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') );
How can I manage this case for different types of components?
Yes it is possible to dynamically create components in React Native based on data you retrieve from the server.
To render the components based on the component key in the JSON config, we first need to create an object that maps the components with the component key. As you can see, I have mapped the component key with the corresponding Reactstrap component. At the top, we will import all the required components.
This should work:
var component = Components[itemData['itemClass']]); return React.createElement(component, { data: itemData, key: itemData['id'] });
You can't use JSX syntax like this <component .../>
because when it gets transpiled component
won't refer to anything.
UPDATE: Here is the updated ItemList component in full:
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> ); } });
You can see it working in this fiddle: http://jsfiddle.net/fmhhtk5o/3/
The accepted answer is not entirely accurate and it is overly complex.
You can't use JSX syntax like this <component .../> because when it gets transpiled component won't refer to anything.
Just capitalize the variable name to avoid this, ie.
const component = ({ChildClass}) => { return <ChildClass /> }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With