--- title: "React Components, Elements, and Instances" author: [gaearon] --- The difference between **components, their instances, and elements** confuses many React beginners. Why are there three different terms to refer to something that is painted on screen? ## Managing the Instances {#managing-the-instances} If you’re new to React, you probably only worked with component classes and instances before. For example, you may declare a `Button` *component* by creating a class. When the app is running, you may have several *instances* of this component on screen, each with its own properties and local state. This is the traditional object-oriented UI programming. Why introduce *elements*? In this traditional UI model, it is up to you to take care of creating and destroying child component instances. If a `Form` component wants to render a `Button` component, it needs to create its instance, and manually keep it up to date with any new information. ```js class Form extends TraditionalObjectOrientedView { render() { // Read some data passed to the view const { isSubmitted, buttonText } = this.attrs; if (!isSubmitted && !this.button) { // Form is not yet submitted. Create the button! this.button = new Button({ children: buttonText, color: 'blue' }); this.el.appendChild(this.button.el); } if (this.button) { // The button is visible. Update its text! this.button.attrs.children = buttonText; this.button.render(); } if (isSubmitted && this.button) { // Form was submitted. Destroy the button! this.el.removeChild(this.button.el); this.button.destroy(); } if (isSubmitted && !this.message) { // Form was submitted. Show the success message! this.message = new Message({ text: 'Success!' }); this.el.appendChild(this.message.el); } } } ``` This is pseudocode, but it is more or less what you end up with when you write composite UI code that behaves consistently in an object-oriented way using a library like Backbone. Each component instance has to keep references to its DOM node and to the instances of the children components, and create, update, and destroy them when the time is right. The lines of code grow as the square of the number of possible states of the component, and the parents have direct access to their children component instances, making it hard to decouple them in the future. So how is React different? ## Elements Describe the Tree {#elements-describe-the-tree} In React, this is where the *elements* come to rescue. **An element is a plain object *describing* a component instance or DOM node and its desired properties.** It contains only information about the component type (for example, a `Button`), its properties (for example, its `color`), and any child elements inside it. An element is not an actual instance. Rather, it is a way to tell React what you *want* to see on the screen. You can’t call any methods on the element. It’s just an immutable description object with two fields: `type: (string | ReactClass)` and `props: Object`[^1]. ### DOM Elements {#dom-elements} When an element’s `type` is a string, it represents a DOM node with that tag name, and `props` correspond to its attributes. This is what React will render. For example: ```js { type: 'button', props: { className: 'button button-blue', children: { type: 'b', props: { children: 'OK!' } } } } ``` This element is just a way to represent the following HTML as a plain object: ```html ``` Note how elements can be nested. By convention, when we want to create an element tree, we specify one or more child elements as the `children` prop of their containing element. What’s important is that both child and parent elements are *just descriptions and not the actual instances*. They don’t refer to anything on the screen when you create them. You can create them and throw them away, and it won’t matter much. React elements are easy to traverse, don’t need to be parsed, and of course they are much lighter than the actual DOM elements—they’re just objects! ### Component Elements {#component-elements} However, the `type` of an element can also be a function or a class corresponding to a React component: ```js { type: Button, props: { color: 'blue', children: 'OK!' } } ``` This is the core idea of React. **An element describing a component is also an element, just like an element describing the DOM node. They can be nested and mixed with each other.** This feature lets you define a `DangerButton` component as a `Button` with a specific `color` property value without worrying about whether `Button` renders to a DOM ` ); ``` This mix and matching helps keep components decoupled from each other, as they can express both *is-a* and *has-a* relationships exclusively through composition: * `Button` is a DOM `