React Primer Converting HTML into React Components

Introduction
React is a JavaScript library developed by Facebook and Instagram for developing reusable user interface components. These UI components can have their own state and properties, while keeping in sync with other components sharing the same data. In very simple words, many consider it as the ‘V’ in MVC. In this article, the readers will learn basics of React, some of the key features and their usage.

Key Features
Some of the key features are JSX, Virtual DOM and downward dataflow. Now, we’ll go through them one by one.

JSX – JavaScript XML syntax
In a nutshell, JSX is the syntax of React, which is nothing but a specialised version of JavaScript. It helps developers write HTML type component markups and binding events. In the very end JSX will eventually be transformed into regular JavaScript. One important thing to note here is that it is not mandatory to use JSX. Let’s glance at the difference between React using pure JavaScript and JSX with a simple example:

render: function() {
return React.DOM.a({
href: 'http://sitepoint.com/'
}, 'React');
}

The code given above renders following anchor tag:

<a href="http://sitepoint.com/">Sitepoint</a>

We need to write the code given below inside of component’s render method in order to render the same anchor tag using JSX syntax:

render: function() {
return <a href="http://facebook.github.io/react">React</a>;
}

Here the JSX Transformer is primarily representing the actual DOM node, that needs to be rendered. You can check out the elaborate and easy to understand documentation for JSX to learn more.

Virtual DOM
The virtual DOM is mirror of the browser’s actual DOM. When an object changes, React first finds out the difference or delta of the changes. After that reconciliation is done to update the DOM with result of the difference found out in the first step. Because of this, React performs well by only re-rending the changed DOM. As React uses virtual DOM, we can also render it in server side to generate server-side React views.

Downward dataflow
The architecture of React only supports downward dataflow. The reasoning behind this is to make the components immutable and only respond to data coming from upstream rather than from each other. This way whenever data gets changed in upstream, any component making use of that data will be automatically be re-rendered to reflect any changes. This kind of data binding can be handled via a methodology called Flux. You can go through the overview of Flux at React documentation hub. It will be worthwhile to note that Flux differs from a typical MVC and behaves like an Event bus by queueing up actions as Promises and executes them as they are received. .

Getting Started
It is very easy to get started with React. All you need to do is download the React starter kit and include react.js it in the document head or simply use a CDN. You can also fork the JSFiddle provided by the React team.

Project Setup

In this tutorial, we’ll take a simple html “radio group” and covert it into react components. Let’s create a new folder called react-project and inside this create another folder called components. Inside react-project, create a file called index.html and Inside components create a file called Demo.jsx.

Using React.js Components

Copy following JSX into the Demo.jsx file:

var Demo = React.createClass({
render: function () {
return (
<div>
<h1>React.js Expertise Demo</h1>
<form>Select your expertise:

<label>
<input name="expertise" type="radio" value="angular" />
Angular.js
</label>

<label>
<input name="expertise" type="radio" value="react" />
React.js
</label>

<label>
<input name="expertise" type="radio" value="ember" />
Ember.js
</label>

<label>
<input name="expertise" type="radio" value="aurelia" />
Aurelia.js
</label>

<label>
<input name="expertise" type="radio" value="meteor" />
Meteor.js
</label>

<label>
<input name="expertise" type="radio" value="other" />
Other
</label>
<label>
Please specify:
<input name="expertise_other" type="text" />
</label>

<input type="submit" />

</form></div>
);
}
});

We created our very first react component called Demo and passed an object to React.createClass. We defined render method to return the HTML that we wanted to render. If you look closely, you’ll see pure HTML radio group inside return for selecting a particular expertise. As we discussed previously, that JSX will be eventually converted to regular JavaScript, you would notice that we have used className in place of class(a reserved word in JS).

Copy following html into index.html file:


React.js Expertise Selection Demo <script src="http://fb.me/react-0.12.2.js"></script><script src="http://fb.me/JSXTransformer-0.12.2.js"></script> <script src="/components/Demo.jsx" type="text/jsx"></script><script type="text/jsx">// <![CDATA[ var demo = React.createElement(Demo); React.render(demo, document.body); // ]]></script>

In our HTML file we have included React, in-browser JSX transformer (to transform JSX file into JavaScript) via CDN and JSX file (Demo.jsx) to link-in the demo component. It is not recommended to use the in-browser JSX transformer in production application, as it is heavy and slow. We’ll learn about better way of JSX transformation in the subsequent part of this tutorial.

Now, in order to render demo component, we are passing it via var demo = React.createElement(Demo); and rending it onto document.body. At this point, you can start a server and see the live radio group in the browser. Download the git repo for this part of tutorial.

Component Refactoring
If you look at out the radio group HTML code, you would notice repetition of paragraph, label and value for all options.


<label> <input name="expertise" type="radio" value="angular" /> Angular.js </label>

So we’ll remove some of that repetition by creating a new component for radio option. Let’s create a new file called radioOption.jsx inside components folder. Copy following code into this new file:

var RadioOption = React.createClass({
render: function () {
return (

<label>
<input name="expertise" type="radio" value="{this.props.value}/" />
{this.props.children}
</label>

);
}
});

Here props object is used to access component’s properties. We are passing value property to the input by{this.props.value} and accessing RadioOption tag’s content by using {this.props.children}. Now, let’s just go back to Demo.jsx file and use RadioOption custom tag to create the radio options. In the end we’ll be left with the text box for other option. As we can’t use RadioOption tag to replace this, we’ll simply create another component RadioOtherOption.jsx file. Copy the following into this file:

var RadioOtherOption = React.createClass({
render: function () {
return (

<label>
<input name="expertise" type="radio" value="other" />
Other
</label>
<label>
Please specify:
<input name="expertise_other" type="text" />
</label>

);
}
});

RadioOtherOption tag can can be used to replace the other option text field in Demo.jsx file. Finally the content of Demo.jsx should be the following:

var Demo = React.createClass({
render: function () {
return (
<div>
<h1>React.js Radio Group Demo</h1>
<form>How did you hear about us?
Angular.js
React.js
Ember.js
Aurelia.js
Meteor.jsĀ 

<input type="submit" />

</form></div>
);
}
});

Download the git repo for component refactoring.

Passing Properties to Components

Till now we converted HTML to React component and added couple of extra components to simplify the code. Now, we’ll further simplify our code by adding another component and passing properties to it. Basically what we need to do is create an array of options and pass that into the new component. We’ll call our new component radioOptionGroup. So, let’s create the JavaScript array of objects in Demo.jsx.

var radioOptions = [
{ value: 'angular', label: 'Angular.js' },
{ value: 'react', label: 'React.js' },
{ value: 'ember', label: 'Ember.js' },
{ value: 'aurelia', label: 'Aurelia.js' },
{ value: 'meteor', label: 'Meteor.js' }
];

We’ll loop through the array and create radioOption components. Now, delete the RadioOption tags, create a RadioOptionGroup tag and pass the radioOptions array as an options property. Given below is the final code of Demo.jsx:

var Demo = React.createClass({
render: function () {
var radioOptions = [
{ value: 'angular', label: 'Angular.js' },
{ value: 'react', label: 'React.js' },
{ value: 'ember', label: 'Ember.js' },
{ value: 'aurelia', label: 'Aurelia.js' },
{ value: 'meteor', label: 'Meteor.js' }
];

return (

            <div className="container">
                <h1>React.js Expertise Selection Demo</h1>

                <form>
                    <p className="h3">Select your expertise:</p>

                    <RadioOptionGroup options={radioOptions} />

                    <p><input type="submit"/></p>
                </form>
            </div>

        );
}
});

Next thing that we need to do is create RadioOptionGroup component. So, create a RadioOptionGroup.jsx and copy the following code:

var RadioOptionGroup = React.createClass({
render: function () {
return (
<div>{this.props.options.map(function (option) {
return ({option.label}

);
})}

</div>
);
}
});

We have the options in the props. So we are looping over that and for each of them, we are creating one of those radio options. We are using map, which is ES5 JavaScript method on arrays. The map method of this.props.options array is called to pass a function which is in turn passing us each option as RadioOption component. Here, option.value has been used to fetch option value and option.label to fetch option label. While using map, it should be noted that each child in an array should have unique key property, which is key={option.value} in this case. Also, React requires us to return only one root element. So have wrapped all our elements including RadioOtherOption in a div. Download the git repo for property passing.

Toggling Elements
In this section, we’ll be making the Other expertise radio optional. Basically we need to add a property to turn this on or off. Go to Demo.jsx and change <RadioOptionGroup options={radioOptions} /> to <RadioOptionGroup other={true} options={radioOptions} />. Now, let’s open up RadioOptionGroup.jsx and use {this.props.other} to decide whether we would render <RadioOtherOption/> or not. In order to achieve that, we’ll use a ternary expression {this.props.other ? <RadioOtherOption/> : <div/>. So, <RadioOtherOption/> will be rendered whenever other is true, otherwise an empty div will be rendered.

Download the git repo for toggling elements.

Listening to Events
In this section of tutorial, we’ll make the text box appear only when the other option is selected. We are going to achieve that by using something called state. Contrary to props, which are define during componet initialisation, we should think of state as an internal data-set that affects rendering of components. Basically when the other option’s state changes, we would either show or hide the text box Now, let’s head over to RadioOtherOption.jsx file. Here we will add onChange event to the Other radio option and have it call a methodhandleChange. This handleChange will receive an event and event.targetproperty will reference the other radio option. We’ll be using this.setState method to change the state of the component.
Given below is the code for handleChange method:

handleChange: function(event) {
var input = event.target;
this.setState({
checked: input.checked
});
}

Now, we’ll replace the text box with the following:

{this.state.checked ? (
<label>
Please specify:
<input name="expertise_other" type="text" />
</label>
) : null}

The ternary operator will render the text box, whenever the other radio option will be selected. We should note that when this component will render, this.state would be null. So, let’s use getInitialState method to keep the other option in unselected state while rendering the component for the first time. Given below is the code for your reference:

getInitialState: function () {
return {
checked: false
};
}

Following reset method would be added to reset the state to unselected state:

reset : function(){
this.setState({checked : false});
}

Finally, in RadioOptionGroup.jsx file, let’s add ref="radioOther" to radioOtherOption tag. We’ll also add onCheck={self.handleCheck} to RadioOption tag, which will call handleCheck method. This method will be used to reset the other radio option. In the end, RadioOptionGroup.jsx would look like the following:

var RadioOptionGroup = React.createClass({

handleCheck : function(){
if(this.refs.radioOther){
this.refs.radioOther.reset();
}
},

render: function () {
var self = this;
return (
<div>{this.props.options.map(function (option) {
return ({option.label}

);
})}

</div>
{this.props.other ? :
<div></div>
}

);
}
});

Download the final git repo for this tutorial.

Converting JSX to JavaScript

Run the following in your command line: npm install -g react-tools. Create a build directory to hold all the build files and run the following command to create JavaScript files out of the JSX files:
jsx -x jsx components/ build/

This will generate JS files for you to link-in from index.html. You can safely omit the linkage of JSX files along with the JSXTransformer from the index.html.

Conclusion

In this article we learned some of the key concepts of React and JSX. The way React is gaining popularity, it is definitely the framework to look forward to. I hope you’ll experiment with React and finally give it a go in your next project. Don’t forget to checkout some of the popular React APIs and post your queries and feedback via comments.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *