React Elements vs React Components vs Component Backing Instances

Many of you have probably heard of Facebook’s React library and used it in your own work or projects. It’s extremely popular and makes developing user interfaces simple and declarative.

As the title of this post suggests, React has a couple of concepts referenced throughout its documentation that might be confusing to newer React users. For example, if you look at their Glossary, Top-Level API, and Explanation on Refs, and do a quick search for “ReactElement”, “ReactComponent”, and “Component Backing Instance”, you’ll find that these terms are used everywhere and are absolutely core to React.

This post isn’t a React tutorial; it’s more of me just sharing some of what I’ve learned about React recently. Therefore, it’s targeted towards folks who have dabbled with React before, and I’ll assume that you’re familiar with some of the core React concepts and syntax.

What’s a React Element?

The concept of a React Element is central to React, but I honestly believe because its so easy to build user interfaces using React and JSX, it’s possible to miss this concept initially. If you’ve used React with JSX before, it’ll no doubt be second nature to you to write HTML-looking syntax within your JS files. But under the hood, JSX syntax actually compiles down to React function calls — specifically, React.createElement(). And guess what React.createElement() produces? Yup, you guessed it — React Elements. Let’s take a look at the example highlighting the transformation process:

React elements are plain old JavaScript objects with a couple of properties:

  1. key — the key property is used to uniquely identify specific React elements within an array of the same element types. You don’t have to provide a value for it, but if you do, React will be able to perform optimizations making the re-rendering process more efficient.
  2. props — the props property is exactly what you think it is: it’s a mapping of all the props and values passed down to child components.
  3. ref — the ref property is used to access the underlying DOM element associated with a rendered version of this React element.
  4. type — the type property will either be a string value representing any valid HTML element or a reference to a React Component class.

At this point, it’s not important to know all the details around each of these properties. The biggest takeaway is that React elements are simply plain old JavaScript objects used to describe how the HTML for the component should look — there are no methods on the object, just data.

Using the example above, the helloWorld React element tells you that it represents a <div> tag that has the text “Hello World!” as its child node. Even if you created a more complicated JSX example, the React element that’s produced will still just be a JavaScript object with other nested React elements describing how the HTML will look. And if this sounds familiar to you, it’s because this is exactly what the Virtual DOM is — it’s a description of what the DOM should look like at any given time, and it’s declaratively represented by React elements.

What’s a React Component?

Unlike React Elements, you’re probably a bit more familiar with React Components. If you’ve ever written any code like the example below, then you’ve created React Component classes before:

This is written using ES2015's new Class syntax, but its pretty much equivalent to using React.createClass(). You’re probably familiar with writing these component classes, but the important point is that ReactComponents (as described in React’s documentation) refer to an instance of a React component class.

If you’re familiar with JavaScript, you’re probably thinking the “new” operator when you hear the phrase “instance of a class” and your intuition is correct. However, you never use the “new” operator to create React Components. Instead, you’ll use ReactDOM.render() to render a React Element into a particular DOM element, and the return value of ReactDOM.render() will be the React Component instance.

The component instance returned from ReactDOM.render() can call methods defined in the React Component class. This makes sense if you take a step back and remember that ReactDOM.render() is just React’s way of instantiating a Component for you. More often than not, you won’t need access to the component instance itself but I’ve found it helpful to save a reference to the component instance when I’m testing my React Components.

A final interesting tidbit related to ReactDOM.render() is that this is where React performs the efficient diff’ing algorithm on the Virtual DOM. If you recall, React Elements represent the Virtual DOM and this implies that ReactDOM.render() takes in a Virtual DOM, renders it into an actual DOM element, and then returns the component instance. Behind the scenes, if you pass the same React Element type (with possibly different props values) into the same DOM element for ReactDOM.render(), React performs the diff’ing algorithm and only makes the minimal amount of changes needed to the DOM element. And maybe surprisingly, it returns the same component instance each time — except with updated prop and state values.

What’s a Component Backing Instance?

The previous 2 sections explored React Elements and React Component instances — both of which are abstraction layers over the DOM. Now we’ll talk about the term “Component Backing Instance” and how they’re related to the actual DOM elements themselves.

In the previous example, ReactDOM.render() produces a component instance by rendering a React element into an existing DOM element. But as we already know, the component instance isn’t the actual DOM node. However, accessing the underlying DOM node associated with the component instance is actually pretty easy — we use ReactDOM.findDOMNode() and pass in the component instance as the argument. So what does this have to do with the term “component backing instance?” Anticlimactically, React refers to this actual DOM node as the Component backing instance throughout its documentation.

Recap

The 3 terms “React Element”, “React Component”, and “Component Backing Instance” are intimately related. You can think of React elements as the foundational building block since JSX syntax gets transpiled to React.createElement() calls, and end up returning plain old JavaScript objects that we refer to as React elements. React component instances represent the next layer of abstraction — ReactDOM.render() takes in a React element and a reference to an actual DOM node and returns a React component instance. This instance has access to the methods defined in the Component class but outside of unit testing, it is more rarely used. Neither React elements nor React component instances represent actual DOM elements. The DOM element that results from rendering the component instance is referred to as the component backing instance, and the primary way to access it is using ReactDOM.findDOMNode().

I hope this post was able to help clarify these terms for you!