Framing the problem
In our last post we had to manually create two instances of our Liquid component on separate DOM nodes (you can check out the code here). With a small number of components this is okay, but what if we had to spin up a hundred components that had different props being passed to each of them?
Iterating & rendering new components
This is actually a very common occurrence in React, and the way you solve it is by creating a parent component that iterates and instantiates components from an array. For example, lets create a “LiquidsList” component that accepts an array of objects. Then, we’ll iterate through each of those objects and will pass them to a <Liquid />
component:
var LiquidsList = React.createClass({
render: function() {
var liquids = this.props.liquids.map(function(liquidObject, index){
return <Liquid config={ liquidObject } key={ index } />;
})
return (
<div>
{ liquids }
</div>
);
}
});
To make this work, we’ll remove all of our old ReactDOM initializations and replace it with this instead:
// Create object to hold water's name, freezing & boiling points
var water = {
name: "Water",
freezing: 32,
boiling: 212
};
// Create object to hold ethanol's name, freezing & boiling points
var ethanol = {
name: "Ethanol",
freezing: -173.2,
boiling: 173.1
};
// Render our LiquidsList component!
ReactDOM.render(<LiquidsList liquids={ [ethanol, water] } />, document.getElementById('container'));
As you’ll see from the working code, we get the same exact result as before — except now it’s trivial to add new liquids! Simply add a new object to the array being passed through the ‘liquids’ attribute and it will instantiate a brand new component.
The big idea here is that React components can include and instantiate other components, whether it be done statically or programmatically like we did here.