Core React Loop
So, we've seen that when we update a state variable by calling the setter function (setCount
), the UI gets updated. But how does this work, exactly?
This question cuts straight to the core of React. The library, after all, is literally named for how it reacts to state changes!
This is a question we're going to keep coming back to, throughout this course, as we build our mental model for how React works. But let's see if we can start answering it!
Let's keep working with our “counter” example:
function Counter() { const [count, setCount] = React.useState(0);
return ( <button onClick={() => setCount(count + 1)}> Value: {count} </button> );}
As a bit of a review, let's talk about what happens when this component is rendered for the first time.
Our Counter
function returns a bunch of JSX. Let's rewrite it in pure JavaScript, so we can see what's really going on here:
function Counter() { const [count, setCount] = React.useState(0);
return React.createElement( 'button', { onClick: () => setCount(count + 1) }, 'Value: ', count );}
When this code runs, React.createElement
produces a React element, which is a plain JavaScript object. It looks something like this:
{ type: 'button', key: null, ref: null, props: { onClick: () => setCount(count + 1), children: 'Value: 0', }, _owner: null, _store: { validated: false }}
As we learned in the last module, React elements are essentially descriptions of the UI we want. We're saying in this case that we want a button that contains the text “Value: 0”.
We could visualize this JavaScript object as the following HTML snippet:
<button> Value: 0</button>
Our React element, that JavaScript object, is describing this DOM structure. React takes that description, and turns it into the real thing. It creates a <button>
DOM node and appends it to the page.
I didn't show the onClick
handler in this little sketch, but it's very much a part of this process. When React creates and injects the <button>
DOM node, it attaches our handler function.
Now, let's think about what happens when this button is clicked.
The setCount
function will be called, and we'll pass in a new value. count
will be incremented, from 0 to 1.
Whenever a state variable is updated, it triggers a re-render. Once again, React will call the Counter
function. This creates a brand-new React element, a new description of the UI we want.
The new React element describes this DOM structure:
<button> Value: 1</button>
(I'm showing it here as HTML since it's easier to demonstrate, but really, React deals with JavaScript objects that describe this markup.)
Each render is like taking a snapshot. We generate a description that shows what the UI should look like, based on the component's props/state. It's like a photo that captures what things were like at a moment in time.
And so, React has two snapshots:
<button> Value: 0</button>
<button> Value: 1</button>
The user clicked the button, and this second snapshot was generated. React now has to figure out how to update the DOM, so that it matches this latest snapshot.
You know those games where you're shown two slightly-different images, and you have to spot the differences?
(Source: Wikipedia)
React essentially has to play this sort of game, hunting for changes between the two snapshots.
This process is known as reconciliation. Using fancy optimized algorithms, React figures out what's changed. It sees that the button's text content has changed from "Value: 0" to "Value: 1".
Once React has solved the puzzle and worked out what's different, it will need to commit these changes. With surgical precision, it updates the DOM, taking care to only tweak the things that need to be tweaked.
In this case, the operation would be something like:
button.innerText = "Value: 1";
This is the fundamental "flow" of React, the core loop. We can visualize this sequence like this:
Mount
When we render the component for the first time, there is no previous snapshot to compare to. And so, React will create all of the necessary DOM nodes from scratch, and inject them into the page.
Note: You can click the boxes to explore each of the 4 stages described above. ✨