Diffing and Rendering in React

Image Credit

So for a while I’ve been taught that React uses state to calculate changes to how the DOM should be displayed but I haven’t felt completely satisfied with that.

The React docs start out explaining how to use React to create simple UIs while ignoring state entirely, like this ticking clock example, which “calls ReactDOM.render() every second from a setInterval() callback:”

function Clock(props) {

return (

<div>

<h1>Hello, world!</h1>

<h2>It is {props.date.toLocaleTimeString()}.</h2>

</div>

);

}

function tick() {

ReactDOM.render(

<Clock date={new Date()} />,

document.getElementById(‘root’)

);

}

setInterval(tick, 1000);

The docs says that “with our knowledge so far, the only way to update the UI is to create a new element, and pass it to ReactDOM.render().” (Reactjs — Rendering Elements)

However, the docs also go on to say that this initial example is not representative of real React components, since “In practice, most React apps only call ReactDOM.render() once. In the next sections we will learn how such code gets encapsulated into stateful components.”

I know that React’s diffing algorithm is a key here, but I would like to know what React method eventually gets called to actually re-render components when state is updated.

However, looking at the docs on Reconciliation (diffing), the docs speak generally of a render() function:

“When you use React, at a single point in time you can think of the render() function as creating a tree of React elements. On the next state or props update, that render() function will return a different tree of React elements. React then needs to figure out how to efficiently update the UI to match the most recent tree.”

I’m confused for a minute and eventually my brain coalesces around a google search:

“is reactdom.render the same as the render function in a class component?”

Stack Overflow Answer: No, “There are two separate render() methods in React. One is ReactDOM.render() and the other is Component.render().”

Tl;dr for the stack overflow post (it’s a good explanation though):

ReactDOM.render() method is just for that weird moment where you remember you’ve written everything in React but somehow need that to get slapped onto the root element of the HTML DOM in a simple old-fashioned index.html file. You need an actual webpage with UI.

The Component.render() method is more in the land of pure React. It gets called whenever a component’s props or state change and renders a new React element tree for that component; this is the “virtual” item that gets diffed with an older version of itself in the VDOM.

So the actual diffing process is carried out by ReactDOM.render(): “ReactDOM.render() controls the contents of the container node you pass in. Any existing DOM elements inside are replaced when first called. Later calls use React’s DOM diffing algorithm for efficient updates.”

So Component.render() just creates new virtual DOM elements; it’s ReactDOM.render()’s job to figure out what the app should actually look like in the browser. In this way, I understand why the docs said earlier that ReactDOM.render() in most apps is only called once. Serially calling it every second via setInterval() only makes sense in the context of a simple ticking clock app; for more complicated apps relying on multiple components, using state to encapsulate each component’s UI across different moments in time enables us to treat the app’s state updates in a modularized way and update flexibly only the things that need to be updated, rather than the entire app. Fast, minimal updates are the whole point of React, and entrusting state to dictate updates to UI is how React sets out to accomplish this.

PS: one extra way to remember that Component.render() and ReactDOM.render() are entirely different functions (especially while reading through the docs just talking about a “render()” method without further context): ReactDOM.render() takes arguments, Component.render() doesn’t.

QUESTIONS THAT MADE ME WANT TO KNOW ABOUT THIS

- I want to know how React works as a waterfall over time:

is the same component constantly being re-instantiated? (Re: this quote: “An element is like a single frame in a movie: it represents the UI at a certain point in time.”)

- Answer: No, React Docs-Reconciliation says: “When a component updates, the instance stays the same so that state is maintained across renders.”

- Curious how diffing works?

- Answer: it’s complicated, refer to docs. I think I can look past the nitty gritty mechanics of how heuristic diffing actually works, but I haven’t completely answered an important macro question still which is: how do the different VDOM versions get lined up and assessed side by side?

- What is being called downstream of setState() updating state, i.e., what is triggered by updating state?

- Answer: I think it should work like this: first the individual component’s render method gets called, and that component creates a new React element tree for that component. Then that new React element tree is compared with its equivalent portion of the virtual DOM that corresponds to the actual DOM representation on the screen from a moment ago. Then ReactDOM.render() gets called and diffing of the two virtual trees happens, and when this diffing is finished, ReactDOM.render() renders to the actual DOM the smallest update possible to make the DOM reflect those changes in state. So the stream of events would be: this.setState() => Component.render() => ReactDOM.render()

Software Engineer and Chinese Language Nerd

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store