Thinkster

Utilizing props to create reusable components

The limitation of hard coded components

In our previous post we created a <Water /> component that allows us to change the current temperature and report if water is a liquid, solid or gas at that temperature (you can check out the working code here).

While this component works great for water specifically, what if we wanted to support other types of liquids as well? For example, ethanol’s boiling point is 173.1F and freezing is -173.2F — vastly different from water’s 212F and 32F. So how can we change our component to support the different boiling and freezing points of every liquid in the universe?

Modifying our component to be reusable

The first thing we’ll want to do is change the name of our component from Water to Liquid, as this component isn’t exclusive to water anymore. To do that, we’ll change var Water = React.createClass({ to var Liquid = React.createClass({. In ReactDOM.render we’ll also need to pass in <Liquid /> instead of <Water />.

With that out of the way, lets figure out how to actually make this component reusable with any liquid’s freezing & boiling point!

‘props’ to the rescue

Components can accept data through attributes (which are referred to as “properties”) that allow us to configure our React component. For example, here’s how we could pass ethanol’s name, boiling & freezing points to the Liquid component:

var ethanol = {
    name: "Ethanol",
    freezing: -173.2,
    boiling: 173.1
};
React.render(<Liquid config={ ethanol } />, document.getElementById('container'));

The ‘config’ attribute is simply what we decided to name it for this post — you can custom name attributes as you see fit!

This object can now be accessed via this.props.config, matching our attribute’s name. Lets go ahead and swap out our render’s hard coded water integers with the data now being passed in via props.

The freezing point integer:

if (this.state.currentTemp <= 32) {

is replaced with the freezing integer in our config object:

if (this.state.currentTemp <= this.props.config.freezing) {

And the boiling point integer:

} else if (this.state.currentTemp >= 212) {

is replaced with the boiling integer in our config object:

} else if (this.state.currentTemp >= this.props.config.boiling) {

Finally, we’ll replace the string “water” with the name string provided in the config object:

<p>At { this.state.currentTemp }°F, { this.props.config.name } is considered to be a "{ stateOfMatter }" state of matter.</p>

Multiple instances, different props

Lets spin up two instances of this component — one will have have water’s properties, the other will have ethanol’s properties. To do this, we’ll need to mount the React components on two different DOM nodes and pass along an object to the config attribute for each:

// Create object to hold water's name, freezing & boiling points
var water = {
    name: "Water",
    freezing: 32,
    boiling: 212
};
// Create a div for water powered Liquid component and put it in the container div
var waterEl = document.createElement("div");
document.getElementById('container').appendChild(waterEl);
// Render our Liquid component with water's properties!
ReactDOM.render(<Liquid config={ water }  />, waterEl);

// Create object to hold ethanol's name, freezing & boiling points
var ethanol = {
    name: "Ethanol",
    freezing: -173.2,
    boiling: 173.1
};
// Create a div for our ethanol powered Liquid component and put it in the container div
var ethanolEl = document.createElement("div");
document.getElementById('container').appendChild(ethanolEl);
// Render our Liquid component with ethanol's properties!
ReactDOM.render(<Liquid config={ ethanol } />, ethanolEl);

Check out the working code here! You can now see the two components running, but they show different results with the temperature set to 10F. This makes sense because water is frozen at that temperature, but ethanol is still a liquid!

We’ve created a React component that can determine the physical state of any liquid in the universe — pretty neat, right?