React

Programmatically Rendering Child Components

Outline

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.