Blog

React in modern web applications: Part 1

02 Sep, 2014
Xebia Background Header Wave

At Xebia we love to share knowledge! One of the ways we do this is by organizing 1-day courses during the summer. Together with Frank Visser we decided to do a training about full stack development with Node.js, AngularJS and Facebook’s React. The goal of the training was to show the students how one could create a simple timesheet application. This application would use nothing but modern Javascript technologies while also teaching them best practices with regards to setting up and maintaining it.
To further share the knowledge gained during the creation of this training we’ll be releasing several blog posts. In this first part we’ll talk about why to use React, what React is and how you can incorporate it into your Grunt lifecycle.
This series of blog posts assume that you’re familiar with the Node.js platform and the Javascript task runner Grunt.

What is React?

ReactJS logo
React is a Javascript library for creating user interfaces made by Facebook. It is their answer to the V in MVC. As it only takes care of the user interface part of a web application React can be (and most often will be) combined with other frameworks (e.g. AngularJS, Backbone.js, …) for handling the MC part.
In case you’re unfamiliar with the MVC architecture, it stands for model-view-controller and it is an architectural pattern for dividing your software into 3 parts with the goal of separating the internal representation of data from the representation shown to the actual user of the software.

Why use React?

There are quite a lot of Javascript MVC frameworks which also allow you to model your views. What are the benefits of using React instead of for example AngularJS?
What sets React apart from other Javascript MVC frameworks like AngularJS is the way React handles UI updates. To dynamically update a web UI you have to apply DOM updates whenever data in your UI changes. These DOM updates, compared to reading data from the DOM, are expensive operations which can drastically slow down your application’s responsiveness if you do not minimize the amount of updates you do. React took a clever approach to minimizing the amount of DOM updates by using a virtual DOM (or shadow DOM) diff.
In contrast to the normal DOM consisting of nodes the virtual DOM consists of lightweight Javascript objects that represent your different React components. This representation is used to determine the minimum amount of steps required to go from the previous render to the next render. By using an observable to check if the state has changed React prevents unnecessary re-renders. By calling the setState method you mark a component ‘dirty’ which essentially tells React to update the UI for this component. When setState is called the component rebuilds the virtual DOM for all its children. React will then compare this to the current virtual sub-tree for the same component to determine the changes and thus find the minimum amount of data to update.
Besides efficient updates of only sub-trees, React batches these virtual DOM batches into real DOM updates. At the end of the React event loop, React will look up all components marked as dirty and re-render them.

How does React compare to AngularJS?

It is important to note that you can perfectly mix the usage of React with other frameworks like AngularJS for creating user interfaces. You can of course also decide to only use React for the UI and keep using AngularJS for the M and C in MVC.
In our opinion, using React for simple components does not give you an advantage over using AngularJS. We believe the true strength of React lies in demanding components that re-render a lot. React tends to really outperform AngularJS (and a lot of other frameworks) when it comes to UI elements that require a lot of re-rendering. This is due to how React handles UI updates internally as explained above.

JSX

JSX is a Javascript XML syntax transform recommended for use with React. It is a statically-typed object-oriented programming language designed for modern browsers. It is faster, safer and easier to use than Javascript itself. Although JSX and React are independent technologies, JSX was built with React in mind. React works without JSX out of the box but they do recommend using it. Some of the many reasons for using JSX:

  • It’s easier to visualize the structure of the DOM
  • Designers are more comfortable making changes
  • It’s familiar for those who have used MXML or XAML

If you decide to go for JSX you will have to compile the JSX to Javascript before running your application. Later on in this article I’ll show you how you can automate this using a Grunt task. Besides Grunt there are a lot of other build tools that can compile JSX. To name a few, there are plugins for Gulp, Broccoli or Mimosa.
An example JSX file for creating a simple link looks as follows:

[javascript]
/** @jsx React.DOM */
var link = React.DOM.a({href: 'https://facebook.github.io/react'}, 'React');
[/javascript]

Make sure to never forget the starting comment or your JSX file will not be processed by React.

Components

With React you can construct UI views using multiple, reusable components. You can separate the different concepts of your application by creating modular components and thus get the same benefits when using functions and classes. You should strive to break down the different common elements in your UI into reusable components that will allow you to reduce boilerplate and keep it DRY.
You can construct component classes by calling React.createClass() and each component has a well-defined interface and can contain state (in the form of props) specific to that component. A component can have ownership over other components and in React, the owner of a component is the one setting the props of that component. An owner, or parent component can access its children by calling this.props.children.
Using React you could create a hello world application as follows:

[javascript]
/** @jsx React.DOM */
var HelloWorld = React.createClass({
render: function() {
return <div>Hello world!</div>;
}
});
[/javascript]

Creating a component does not mean it will get rendered automatically. You have to define where you would like to render your different components using React.renderComponent as follows:

[javascript]
React.renderComponent(<HelloWorld />, targetNode);
[/javascript]

By using for example document.getElementById or a jQuery selector you target the DOM node where you would like React to render your component and you pass it on as the targetNode parameter.

Automating JSX compilation in Grunt

To automate the compilation of JSX files you will need to install the grunt-react package using Node.js’ npm installer:
npm install grunt-react –save-dev
After installing the package you have to add a bit of configuration to your Gruntfile.js so that the task knows where your JSX source files are located and where and with what extension you would like to store the compiled Javascript files.

[javascript]
react: {
dynamic_mappings: {
files: [
{
expand: true,
src: ['scripts/jsx/*.jsx'],
dest: 'app/build_jsx/',
ext: '.js'
}
]
}
}
[/javascript]

To speed up development you can also configure the grunt-contrib-watch package to keep an eye on JSX files. Watching for JSX files will allow you to run the grunt-react task whenever you change a JSX file resulting in continuous compilation of JSX files while you develop your application. You simply specify the type of files to watch for and the task that you would like to run when one of these files changes:

[javascript]
watch: {
jsx: {
files: ['scripts/jsx/*.jsx'],
tasks: ['react']
}
}
[/javascript]

Last but not least you will want to add the grunt-react task to one or more of your grunt lifecycle tasks. In our setup we added it to the serve and build tasks.

[javascript]
grunt.registerTask('serve', function (target) {
if (target === 'dist') {
return grunt.task.run(['build', 'connect:dist:keepalive']);
}
grunt.task.run([
'clean:server',
'bowerInstall',
<strong>'react',</strong>
'concurrent:server',
'autoprefixer',
'configureProxies:server',
'connect:livereload',
'watch'
]);
});
grunt.registerTask('build', [
'clean:dist',
'bowerInstall',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
<strong>'react',</strong>
'ngmin',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'rev',
'usemin',
'htmlmin'
]);
[/javascript]

Conclusion

Due to React’s different approach on handling UI changes it is highly efficient at re-rendering UI components. Besides that it’s easily configurable and integrate in your build lifecycle.

What’s next?

In the next article we’ll be discussing how you can use React together with AngularJS, how to deal with state in your components and how to avoid passing through your entire component hierarchy using callbacks when updating state.

Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts