Creating React Nodes

In most cases developers using React will favor JSX and use it to create React nodes. Despite this, in this chapter we are going to examine how React nodes can be created without JSX, using only JavaScript. The next chapter will discuss creating React nodes using JSX.

Creating React nodes using JavaScript is as simple as calling the React.createElement(type,props,children) function and passing it a set of arguments defining an actual DOM node (e.g., type = an html element e.g., <li> or custom element e.g., <my-li>).

The React.createElement() arguments are explained below:

  • type (string | React.createClass()):

    Can be a string which represents an HTML element (or custom HTML element) or React component instance (i.e., an instance of React.createClass())

  • props (null | object):

    Can be null or an object containing attributes/props and values

  • children (null | string | React.createClass() | React.createElement()):

    Children can be null, a string that gets turned into a text node, an instance of React.createClass() or React.createElement()

Below I use the React.createElement() function to create a virtual DOM representation of a <li> element node containing a text node of one (a.k.a., React text) and an id of li1.

  1. var reactNodeLi = React.createElement('li', {id:'li1'}, 'one');

Notice that the first argument defines the HTML element I want to represent. The second argument defines the attributes/props on the <li>. And the third argument defines what the node inside of the element will be. In this case, I am simply placing a child text node (i.e., 'one') inside the <li>. The last argument that becomes a child of the node being created can be

  • A React text node
  • A React element node, or
  • A React component instance.

At this point all I’ve done is create a React element node containing a React text node that I have stored into the variable reactNodeLi. To create a virtual DOM we have to actually render the React element node to a real DOM. To do this we use the ReactDOM.render() function.

  1. ReactDOM.render(reactNodeLi, document.getElementById('app'));

The above code, loosely stated, invokes the following:

  1. Create a virtual DOM constructed from the React element node passed in (reactNodeLi)
  2. Use the virtual DOM to re-construct a real DOM branch
  3. Insert the real DOM branch (i.e., <li id="li1">one</li>) into the DOM as a child node of <div id="app"></div>.

In other words, the HTML DOM changes from this:

  1. <div id="app"></div>

to this:

  1. <div id="app">
  2. //note that React added the react data-reactid attribute
  3. <li id="li1" data-reactid=".0">one</li>
  4. </div>

This was a rather simplistic example. Using React.createElement() a complex structure can be created as well. For example, below I’m using React.createElement() to create a bunch of React nodes representing an HTML unordered list of text words (i.e., <ul>).

  1. // Create React element <li>'s
  2. var rElmLi1 = React.createElement('li', {id:'li1'}, 'one'),
  3. rElmLi2 = React.createElement('li', {id:'li2'}, 'two'),
  4. rElmLi3 = React.createElement('li', {id:'li3'}, 'three');
  5. // Create <ul> React element and add child
  6. // React <li> elements to it
  7. var reactElementUl = React.createElement('ul', {className:'myList'}, rElmLi1, rElmLi2, rElmLi3);

Before rendering the unordered list to the DOM I think it is worth showing that the above code can be simplified by using the React.createElement() in place of variables. This also demonstrates how a hierarchy or DOM branch can be defined using JavaScript.

  1. var reactElementUl = React.createElement(
  2. 'ul', {
  3. className: 'myList'
  4. },
  5. React.createElement('li', {id: 'li1'}, 'one'),
  6. React.createElement('li', {id: 'li2'}, 'two'),
  7. React.createElement('li', {id: 'li3'}, 'three')
  8. );

When the above code is rendered to the DOM the resulting HTML will look like:

  1. <ul class="myList" data-reactid=".0">
  2. <li id="li1" data-reactid=".0.0">one</li>
  3. <li id="li2" data-reactid=".0.1">two</li>
  4. <li id="li3" data-reactid=".0.2">three</li>
  5. </ul>

You can investigate this yourself using the JSFiddle below:

source code

It should be obvious that React nodes are just JavaScript objects in a tree that represent real DOM nodes inside of a virtual DOM tree. The virtual DOM is then used to construct an actual DOM branch in an HTML page.

Notes

  • The type argument passed to React.createElement(type, props, children) can be
    • A string indicating a standard HTML element (e.g., 'li' = <li></li>), or
    • A custom element (e.g., 'foo-bar' = <foo-bar></foo-bar>, or a React component instance (i.e., an instance of React.createClass().
  • These are the standard HTML elements that React supports (i.e. these elements passed as a string type to createElement()). They create the associating standard HTML element in the DOM):
  1. a abbr address area article aside audio b base bdi bdo big blockquote body br
  2. button canvas caption cite code col colgroup data datalist dd del details dfn
  3. dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5
  4. h6 head header hgroup hr html i iframe img input ins kbd keygen label legend li
  5. link main map mark menu menuitem meta meter nav noscript object ol optgroup
  6. option output p param picture pre progress q rp rt ruby s samp script section
  7. select small source span strong style sub summary sup table tbody td textarea
  8. tfoot th thead time title tr track u ul var video wbr