Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon

Create Your First React Element

Save for later
  • 22 min read
  • 17 Feb 2016

article-image

From the 7th to the 13th of November 2016, you can save up to 80% on some of our top ReactJS content - so what are you waiting for? Dive in here before the week ends!

As many of you know, creating a simple web application today involves writing the HTML, CSS, and JavaScript code. The reason we use three different technologies is because we want to separate three different concerns:

  • Content (HTML)
  • Styling (CSS)
  • Logic (JavaScript)

(For more resources related to this topic, see here.)

This separation works great for creating a web page because, traditionally, we had different people working on different parts of our web page: one person structured the content using HTML and styled it using CSS, and then another person implemented the dynamic behavior of various elements on that web page using JavaScript. It was a content-centric approach.

Today, we mostly don't think of a website as a collection of web pages anymore. Instead, we build web applications that might have only one web page, and that web page does not represent the layout for our content—it represents a container for our web application. Such a web application with a single web page is called (unsurprisingly) a Single Page Application (SPA). You might be wondering, how do we represent the rest of the content in a SPA? Surely, we need to create an additional layout using HTML tags? Otherwise, how does a web browser know what to render?

create-your-first-react-element-img-0

These are all valid questions. Let's take a look at how it works in this article. Once you load your web page in a web browser, it creates a Document Object Model (DOM) of that web page. A DOM represents your web page in a tree structure, and at this point, it reflects the structure of the layout that you created with only HTML tags. This is what happens regardless of whether you're building a traditional web page or a SPA. The difference between the two is what happens next. If you are building a traditional web page, then you would finish creating your web page's layout. On the other hand, if you are building a SPA, then you would need to start creating additional elements by manipulating the DOM with JavaScript. A web browser provides you with the JavaScript DOM API to do this. You can learn more about it at https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model.

However, manipulating (or mutating) the DOM with JavaScript has two issues:

  • Your programming style will be imperative if you decide to use the JavaScript DOM API directly. This programming style leads to a code base that is harder to maintain.
  • DOM mutations are slow because they cannot be optimized for speed, unlike other JavaScript code.

Luckily, React solves both these problems for us.

Understanding virtual DOM

Why do we need to manipulate the DOM in the first place? Because our web applications are not static. They have a state represented by the user interface (UI) that a web browser renders, and that state can be changed when an event occurs. What kind of events are we talking about? There are two types of events that we're interested in:

  • User events: When a user types, clicks, scrolls, resizes, and so on
  • Server events: When an application receives data or an error from a server, among others

What happens while handling these events? Usually, we update the data that our application depends on, and that data represents a state of our data model. In turn, when a state of our data model changes, we might want to reflect this change by updating a state of our UI. Looks like what we want is a way of syncing two different states: the UI state and the data model state. We want one to react to the changes in  the other and vice versa. How can we achieve this?

One of the ways to sync your application's UI state with an underlying data model's state is two-way data binding. There are different types of two-way data binding. One of them is key-value observing (KVO), which is used in Ember.js, Knockout, Backbone, and iOS, among others. Another one is dirty checking, which is used in Angular.

Instead of two-way data binding, React offers a different solution called the virtual DOM. The virtual DOM is a fast, in-memory representation of the real DOM, and it's an abstraction that allows us to treat JavaScript and DOM as if they were reactive. Let's take a look at how it works:

  1. Whenever the state of your data model changes, the virtual DOM and React will rerender your UI to a virtual DOM representation.
  2. React then calculates the difference between the two virtual DOM representations: the previous virtual DOM representation that was computed before the data was changed and the current virtual DOM representation that was computed after the data was changed. This difference between the two virtual DOM representations is what actually needs to be changed in the real DOM.
  3. React updates only what needs to be updated in the real DOM.

The process of finding a difference between the two representations of the virtual DOM and rerendering only the updated patches in a real DOM is fast. Also, the best part is, as a React developer, that you don't need to worry about what actually needs to be rerendered. React allows you to write your code as if you were rerendering the entire DOM every time your application's state changes.

If you would like to learn more about the virtual DOM, the rationale behind it, and how it can be compared to data binding, then I would strongly recommend that you watch this very informative talk by Pete Hunt from Facebook at https://www.youtube.com/watch?v=-DX3vJiqxm4.

Now that we've learnt about the virtual DOM, let's mutate a real DOM by installing React and creating our first React element.

Installing React

To start using the React library, we need to first install it. I am going to show you two ways of doing this: the simplest one and the one using the npm install command.

The simplest way is to add the <script> tag to our ~/snapterest/build/index.html file:

  • For the development version of React, add the following command:
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0-beta3/react.js"></script>

  • For the production version version of React, add the following command:
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0-beta3/react.min.js"></script>

For our project, we'll be using the development version of React.

At the time of writing, the latest version of React library is 0.14.0-beta3. Over time, React gets updated, so make sure you use the latest version that is available to you, unless it introduces breaking changes that are incompatible with the code samples provided in this article. Visit https://github.com/fedosejev/react-essentials to learn about any compatibility issues between the code samples and the latest version of React.

We all know that Browserify allows us to import all the dependency modules for our application using the require() function. We'll be using require() to import the React library as well, which means that, instead of adding a <script> tag to our index.html, we'll be using the npm install command to install React:

  1. Navigate to the ~/snapterest/ directory and run this command: 
    npm install --save react@0.14.0-beta3 react-dom@0.14.0-beta3

  2. Then, open the ~/snapterest/source/app.js file in your text editor and import the React and ReactDOM libraries to the React and ReactDOM variables, respectively:
    var React = require('react');
    
    var ReactDOM = require('react-dom');

The react package contains methods that are concerned with the key idea behind React, that is, describing what you want to render in a declarative way. On the other hand, the react-dom package offers methods that are responsible for rendering to the DOM. You can read more about why developers at Facebook think it's a good idea to separate the React library into two packages at https://facebook.github.io/react/blog/2015/07/03/react-v0.14-beta-1.html#two-packages.

Now we're ready to start using the React library in our project. Next, let's create our first React Element!

Creating React Elements with JavaScript

We'll start by familiarizing ourselves with a fundamental React terminology. It will help us build a clear picture of what the React library is made of. This terminology will most likely update over time, so keep an eye on the official documentation at http://facebook.github.io/react/docs/glossary.html.

Just like the DOM is a tree of nodes, React's virtual DOM is a tree of React nodes. One of the core types in React is called ReactNode. It's a building block for a virtual DOM, and it can be any one of these core types:

  • ReactElement: This is the primary type in React. It's a light, stateless, immutable, virtual representation of a DOM Element.
  • ReactText: This is a string or a number. It represents textual content and it's a virtual representation of a Text Node in the DOM.

ReactElements and ReactTexts are ReactNodes. An array of ReactNodes is called a ReactFragment. You will see examples of all of these in this article.

Let's start with an example of a ReactElement:

  1. Add the following code to your ~/snapterest/source/app.js file:
    var reactElement = React.createElement('h1');
    
    ReactDOM.render(reactElement, document.getElementById('react-application'));

  2. Now your app.js file should look exactly like this:
    var React = require('react');
    
    var ReactDOM = require('react-dom');
    
    var reactElement = React.createElement('h1');
    
    ReactDOM.render(reactElement, document.getElementById('react-application'));

  3. Navigate to the ~/snapterest/ directory and run Gulp's default task:
    gulp
    You will see the following output:
    
    Starting 'default'...

  4. Finished 'default' after 1.73 s
    Navigate to the ~/snapterest/build/ directory, and open index.html in a web browser. You will see a blank web page. Open Developer Tools in your web browser and inspect the HTML markup for your blank web page. You should see this line, among others:
    <h1 data-reactid=".0"></h1>

Well done! We've just created your first React element. Let's see exactly how we did it.

The entry point to the React library is the React object. This object has a method called createElement() that takes three parameters: type, props, and children:

React.createElement(type, props, children);

Let's take a look at each parameter in more detail.

The type parameter

The type parameter can be either a string or a ReactClass:

  • A string could be an HTML tag name such as 'div', 'p', 'h1', and so on. React supports all the common HTML tags and attributes. For a complete list of HTML tags and attributes supported by React, you can refer to http://facebook.github.io/react/docs/tags-and-attributes.html.
  • A ReactClass is created via the React.createClass() method.

The type parameter describes how an HTML tag or a ReactClass is going to be rendered. In our example, we're rendering the h1 HTML tag.

The props parameter

The props parameter is a JavaScript object passed from a parent element to a child element (and not the other way around) with some properties that are considered immutable, that is, those that should not be changed.

While creating DOM elements with React, we can pass the props object with properties that represent the HTML attributes such as class, style, and so on. For example, run the following commands:

Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at ₹800/month. Cancel anytime

var React = require('react');

var ReactDOM = require('react-dom');

var reactElement = React.createElement('h1', { className: 'header' });

ReactDOM.render(reactElement, document.getElementById('react-application'));

The preceding code will create an h1 HTML element with a class attribute set to header:

<h1 class="header" data-reactid=".0"></h1>

Notice that we name our property className rather than class. The reason is that the class keyword is reserved in JavaScript. If you use class as a property name, it will be ignored by React, and a helpful warning message will be printed on the web browser's console:

Warning: Unknown DOM property class. Did you mean className?
Use className instead.

You might be wondering what this data-reactid=".0" attribute is doing in our h1 tag? We didn't pass it to our props object, so where did it come from? It is added and used by React to track the DOM nodes; it might be removed in a future version of React.

The children parameter

The children parameter describes what child elements this element should have, if any. A child element can be any type of ReactNode: a virtual DOM element represented by a ReactElement, a string or a number represented by a ReactText, or an array of other ReactNodes, which is also called ReactFragment.

Let's take a look at this example:

var React = require('react');

var ReactDOM = require('react-dom');

var reactElement = React.createElement('h1', { className: 'header' }, 'This is React');

ReactDOM.render(reactElement, document.getElementById('react-application'));

The following code will create an h1 HTML element with a class attribute and a text node, This is React:

<h1 class="header" data-reactid=".0">This is React</h1>

The h1 tag is represented by a ReactElement, while the This is React string is represented by a ReactText.

Next, let's create a React element with a number of other React elements as it's children:

var React = require('react');

var ReactDOM = require('react-dom');

 

var h1 = React.createElement('h1', { className: 'header', key: 'header' }, 'This is React');

var p = React.createElement('p', { className: 'content', key: 'content' }, "And that's how it works.");

var reactFragment = [ h1, p ];

var section = React.createElement('section', { className: 'container' }, reactFragment);

 

ReactDOM.render(section, document.getElementById('react-application'));

We've created three React elements: h1, p, and section. h1 and p both have child text nodes, "This is React" and "And that's how it works.", respectively. The section has a child that is an array of two ReactElements, h1 and p, called reactFragment. This is also an array of ReactNodes. Each ReactElement in the reactFragment array must have a key property that helps React to identify that ReactElement. As a result, we get the following HTML markup:

<section class="container" data-reactid=".0">

  <h1 class="header" data-reactid=".0.$header">This is React</h1>

  <p class="content" data-reactid=".0.$content">And that's how it works.</p>

</section>

Now we understand how to create React elements. What if we want to create a number of React elements of the same type? Does it mean that we need to call React.createElement('type') over and over again for each element of the same type? We can, but we don't need to because React provides us with a factory function called React.createFactory(). A factory function is a function that creates other functions. This is exactly what React.createFactory(type) does: it creates a function that produces a ReactElement of a given type.

Consider the following example:

var React = require('react');

var ReactDOM = require('react-dom');

 

var listItemElement1 = React.createElement('li', { className: 'item-1', key: 'item-1' }, 'Item 1');

var listItemElement2 = React.createElement('li', { className: 'item-2', key: 'item-2' }, 'Item 2');

var listItemElement3 = React.createElement('li', { className: 'item-3', key: 'item-3' }, 'Item 3');

 

var reactFragment = [ listItemElement1, listItemElement2, listItemElement3 ];

var listOfItems = React.createElement('ul', { className: 'list-of-items' }, reactFragment);

 

ReactDOM.render(listOfItems, document.getElementById('react-application'));

The preceding example produces this HTML:

<ul class="list-of-items" data-reactid=".0">

  <li class="item-1" data-reactid=".0.$item-1">Item 1</li>

  <li class="item-2" data-reactid=".0.$item-2">Item 2</li>

  <li class="item-3" data-reactid=".0.$item-3">Item 3</li>

</ul>

We can simplify it by first creating a factory function:

var React = require('react');

var ReactDOM = require('react-dom');

var createListItemElement = React.createFactory('li');

var listItemElement1 = createListItemElement({ className: 'item-1', key: 'item-1' }, 'Item 1');

var listItemElement2 = createListItemElement({ className: 'item-2', key: 'item-2' }, 'Item 2');

var listItemElement3 = createListItemElement({ className: 'item-3', key: 'item-3' }, 'Item 3');

var reactFragment = [ listItemElement1, listItemElement2, listItemElement3 ];

var listOfItems = React.createElement('ul', { className: 'list-of-items' }, reactFragment);

ReactDOM.render(listOfItems, document.getElementById('react-application'));

In the preceding example, we're first calling the React.createFactory() function and passing a li HTML tag name as a type parameter. Then, the React.createFactory() function returns a new function that we can use as a convenient shorthand to create elements of type li. We store a reference to this function in a variable called createListItemElement. Then, we call this function three times, and each time we only pass the props and children parameters, which are unique for each element. Notice that React.createElement() and React.createFactory() both expect the HTML tag name string (such as li) or the ReactClass object as a type parameter.

React provides us with a number of built-in factory functions to create the common HTML tags. You can call them from the React.DOM object; for example, React.DOM.ul(), React.DOM.li(), React.DOM.div(), and so on. Using them, we can simplify our previous example even further:

var React = require('react');

var ReactDOM = require('react-dom');

 

var listItemElement1 = React.DOM.li({ className: 'item-1', key: 'item-1' }, 'Item 1');

var listItemElement2 = React.DOM.li({ className: 'item-2', key: 'item-2' }, 'Item 2');

var listItemElement3 = React.DOM.li({ className: 'item-3', key: 'item-3' }, 'Item 3');

 

var reactFragment = [ listItemElement1, listItemElement2, listItemElement3 ];

var listOfItems = React.DOM.ul({ className: 'list-of-items' }, reactFragment);

 

ReactDOM.render(listOfItems, document.getElementById('react-application'));

Now we know how to create a tree of ReactNodes. However, there is one important line of code that we need to discuss before we can progress further:

ReactDOM.render(listOfItems, document.getElementById('react-application'));

As you might have already guessed, it renders our ReactNode tree to the DOM. Let's take a closer look at how it works.

Rendering React Elements

The ReactDOM.render() method takes three parameters: ReactElement, a regular DOMElement, and a callback function:

ReactDOM.render(ReactElement, DOMElement, callback);

ReactElement is a root element in the tree of ReactNodes that you've created. A regular DOMElement is a container DOM node for that tree. The callback is a function executed after the tree is rendered or updated. It's important to note that if this ReactElement was previously rendered to a parent DOM Element, then ReactDOM.render() will perform an update on the already rendered DOM tree and only mutate the DOM as it is necessary to reflect the latest version of the ReactElement. This is why a virtual DOM requires fewer DOM mutations.

So far, we've assumed that we're always creating our virtual DOM in a web browser. This is understandable because, after all, React is a user interface library, and all the user interfaces are rendered in a web browser. Can you think of a case when rendering a user interface on a client would be slow? Some of you might have already guessed that I am talking about the initial page load. The problem with the initial page load is the one I mentioned at the beginning of this article—we're not creating static web pages anymore. Instead, when a web browser loads our web application, it receives only the bare minimum HTML markup that is usually used as a container or a parent element for our web application. Then, our JavaScript code creates the rest of the DOM, but in order for it to do so it often needs to request extra data from the server. However, getting this data takes time. Once this data is received, our JavaScript code starts to mutate the DOM. We know that DOM mutations are slow. How can we solve this problem?

The solution is somewhat unexpected. Instead of mutating the DOM in a web browser, we mutate it on a server. Just like we would with our static web pages. A web browser will then receive an HTML that fully represents a user interface of our web application at the time of the initial page load. Sounds simple, but we can't mutate the DOM on a server because it doesn't exist outside a web browser. Or can we?

We have a virtual DOM that is just a JavaScript, and as you know using Node.js, we can run JavaScript on a server. So technically, we can use the React library on a server, and we can create our ReactNode tree on a server. The question is how can we render it to a string that we can send to a client?

React has a method called ReactDOMServer.renderToString() just to do this:

var ReactDOMServer = require('react-dom/server');

ReactDOMServer.renderToString(ReactElement);

It takes a ReactElement as a parameter and renders it to its initial HTML. Not only is this faster than mutating a DOM on a client, but it also improves the Search Engine Optimization (SEO) of your web application.

Speaking of generating static web pages, we can do this too with React:

var ReactDOMServer = require('react-dom/server');

ReactDOM.renderToStaticMarkup(ReactElement);

Similar to ReactDOM.renderToString(), this method also takes a ReactElement as a parameter and outputs an HTML string. However, it doesn't create the extra DOM attributes that React uses internally, it produces shorter HTML strings that we can transfer to the wire quickly.

Now you know not only how to create a virtual DOM tree using React elements, but you also know how to render it to a client and server. Our next question is whether we can do it quickly and in a more visual manner.

Creating React Elements with JSX

When we build our virtual DOM by constantly calling the React.createElement() method, it becomes quite hard to visually translate these multiple function calls into a hierarchy of HTML tags. Don't forget that, even though we're working with a virtual DOM, we're still creating a structure layout for our content and user interface. Wouldn't it be great to be able to visualize that layout easily by simply looking at our React code?

JSX is an optional HTML-like syntax that allows us to create a virtual DOM tree without using the React.createElement() method.

Let's take a look at the previous example that we created without JSX:

var React = require('react');

var ReactDOM = require('react-dom');

 

var listItemElement1 = React.DOM.li({ className: 'item-1', key: 'item-1' }, 'Item 1');

var listItemElement2 = React.DOM.li({ className: 'item-2', key: 'item-2' }, 'Item 2');

var listItemElement3 = React.DOM.li({ className: 'item-3', key: 'item-3' }, 'Item 3');

 

var reactFragment = [ listItemElement1, listItemElement2, listItemElement3 ];

var listOfItems = React.DOM.ul({ className: 'list-of-items' }, reactFragment);

 

ReactDOM.render(listOfItems, document.getElementById('react-application'));

Translate this to the one with JSX:

var React = require('react');

var ReactDOM = require('react-dom');

 

var listOfItems = <ul className="list-of-items">

                    <li className="item-1">Item 1</li>

                    <li className="item-2">Item 2</li>

                    <li className="item-3">Item 3</li>

                  </ul>;
ReactDOM.render(listOfItems, document.getElementById('react-application'));

 

As you can see, JSX allows us to write HTML-like syntax in our JavaScript code. More importantly, we can now clearly see what our HTML layout will look like once it's rendered. JSX is a convenience tool and it comes with a price in the form of an additional transformation step. Transformation of the JSX syntax into valid JavaScript syntax must happen before our "invalid" JavaScript code is interpreted.

We know that the babely module transforms our JSX syntax into a JavaScript one. This transformation happens every time we run our default task from gulpfile.js:

gulp.task('default', function () {

  return browserify('./source/app.js')

        .transform(babelify)

        .bundle()

        .pipe(source('snapterest.js'))

        .pipe(gulp.dest('./build/'));

});

As you can see, the .transform(babelify) function call transforms JSX into JavaScript before bundling it with the other JavaScript code.

To test our transformation, run this command:

gulp

Then, navigate to the ~/snapterest/build/ directory, and open index.html in a web browser. You will see a list of three items.

The React team has built an online JSX Compiler that you can use to test your understanding of how JSX works at http://facebook.github.io/react/jsx-compiler.html.

Using JSX, you might feel very unusual in the beginning, but it can become a very intuitive and convenient tool to use. The best part is that you can choose whether to use it or not. I found that JSX saves me development time, so I chose to use it in this project that we're building. If you choose to not use it, then I believe that you have learned enough in this article to be able to translate the JSX syntax into a JavaScript code with the React.createElement() function calls.

If you have a question about what we have discussed in this article, then you can refer to https://github.com/fedosejev/react-essentials and create a new issue.

Summary

We started this article by discussing the issues with single web page applications and how they can be addressed. Then, we learned what a virtual DOM is and how React allows us to build it. We also installed React and created our first React element using only JavaScript. Then, we also learned how to render React elements in a web browser and on a server. Finally, we looked at a simpler way of creating React elements with JSX.

Resources for Article:


Further resources on this subject: