What Is React Reconciliation?

Photo by Anthony DELANOIX on Unsplash

In order for React to be as fast as it is, it only needs to update the parts of the DOM that need it. You really don’t need to worry about doing this yourself, but understanding how setState() in React works could be beneficial.

The render() Function

The render() function in React creates a tree of React elements. When you pass props down and those props update, the render() function returns a different tree of elements. React would need to figure out how to accomplish this, and, while doing so, make it efficient and fast.

The Virtual DOM

This tree of elements is called the virtual DOM and when a component’s state changes, React uses a diffing algorithm to compare both the DOM and virtual DOM. The virtual DOM will contain the new state of a component.

Take this code from CSS-Tricks:

class App extends React.Component {

  state = {
    result: '',
    entry1: '',
    entry2: ''
  }

  handleEntry1 = (event) => {
    this.setState({entry1: event.target.value})
  }

  handleEntry2 = (event) => {
    this.setState({entry2: event.target.value})
  }

  handleAddition = (event) => {
    const firstInt = parseInt(this.state.entry1)
    const secondInt = parseInt(this.state.entry2)
    this.setState({result: firstInt + secondInt })
  }

  render() {
    const { entry1, entry2, result } = this.state
    return(
      <div>  
        <div>
          <p>Entry 1: { entry1 }</p>
          <p>Entry 2: { entry2 }</p>
          <p>Result: { result }</p>
        </div>
        <br />
        <div>
          Entry 1: 
          <input type='text' onChange={this.handleEntry1} />
        </div>
        <br />
        <div>
          Entry 2: 
          <input type='text' onChange={this.handleEntry2} />
        </div>
        <div>
          <button onClick={this.handleAddition} type='submit'>Add</button>
        </div>
      </div>
    )
  }
}

We set up the initial state to an object which will expect some input. This is the App component. When an input is captured in the entry field, React will create a new tree to which the virtual DOM and will contain the new state for entry1. React will look at both the virtual DOM and the browser DOM and with comparison determine what the differences are and update only the different element in the tree.

A new tree/virtual DOM is created each time state changes in the App component.

Mounting/Unmounting on State Change

When state in a component changes, React will unmount the component and tear the whole tree down and then builds a new one from scratch. Every node in this tree will be destroyed.

To get an example of this, check out this pen I forked below:

See the Pen reconciliation-2 Pen by Tiffany White (@twhite96) on CodePen.

Why This Matters

The way React handles state and state changes makes it really fast. You’ll need to be careful to adhere to its heuristics and conventions or else performance will degrade. With that said, it is pretty easy to build a performant app in React.

Wrapping Things Up

There are a few things I didn’t go over in this article but I suggest you read the React docs on reconciliation.


If you like the blog, you’ll love the newsletter: little letters to you.

How to Bind this in React Without a Constructor

this in React is a reference to the current component. Usually this in React is bound to its built-in methods so that when you want to update state or use an event handler on a form, you could do something like this:

<input type="text" ref={this.someInput} required placeholder="This is a Method" defaultValue={getSomeMethod()}/>

where this.someInput is passing state to whichever React component you are rendering.

Unfortunately, though, React doesn’t auto-bind this to custom methods. This means if I wanted to manipulate the DOM by getting some input, which you can’t do as you can with normal JavaScript, I would create a ref to do whatever DOM tinkering I wanted.

But because React doesn’t auto-bind this, the following code would output undefined when logged:

someInput = React.createRef();
  renderSomeInput (event) {
    event.preventDefault();
    const someFunction = this.someInput.value.value;
    console.log(this);
  }

In order to avoid this, we could use the constructor function in order to initialize or get the state we want:

class SomeCompenent extends React.Component {
  constructor() {
    super();
    this.renderSomeInput.bind(this);
  }
}

While this is a decent way to initialize state, what if you wanted to bind several custom methods in one component? It would get pretty messy…

class SomeCompenent extends React.Component {
  constructor() {
    super();
    this.renderSomeInput.bind(this);
    this.renderSomeInput.bind(this);
    this.renderSomeInput.bind(this);
    this.renderSomeInput.bind(this);
   }
}

You get the idea.

Instead, we can bind this to custom React methods by declaring a method and assigning it to an arrow function:

class SomeCompenent extends React.Component {

  someInput = React.createRef();
    renderSomeInput = (event) =>  {
    event.preventDefault();
    const someFunction = this.someInput.value.value;
    console.log(this);
    }
  }

which will allow us to bind the value of this to the SomeComponent component.