How react's rendering flow works
Douglas Almeida
Posted on August 27, 2024
To create a healthy application, it's important to understand How react's rendering flow works, and what happens when a stage changes.
This topic is quite expensive, but I will try to summarize this topic in a way that you can understand.
Let's start!
Flow stages
The flow basically happens in three stages:
- Trigger a render
- React renders your components
- React commits changes to the dom
Let's go through each one.
Have you ever wondered what the meaning of this code is?
Basically, it's the entry point of our application usually meaning main.tsx
or index.tsx
, this file is responsible for initial rendering, "React will establish a root for the domNode and handle the DOM management within it.
<App />
component is our root component, all our flow needs to go through it, Routes, Providers and etc...
The first rendering will be based on this guy.
Ok, now we know how to work initial render, let's understand when react re-rendering a component.
React will re-rendering a component in three situations:
- Hooks Changed (useState, Context, useReducer, UseEffect and etc..)
- Props Changed
- Parent Component re-rendered
When it happens React will:
- Recreate HTML of this component
- Will Compare with the old version
- If something changes, it will rewrite/commit HTML on the screen (React won't unmount and mount component again, re-render will only modify what changes in the component).
This whole process isn't done directly in real DOM, because it could be
slow and costly in terms of performance, react uses VIRTUAL DOM and the guy responsible for these calculations it's called RECONCILIATION.
Virtual DOM: The Virtual DOM is a lightweight copy of the real DOM used by React.
Reconciliation/Diffing Algorithm: React compares the current Virtual DOM with the previous one to identify changes (diffs), Based on these differences, React efficiently determines the necessary updates to the real DOM, targeting only the changed parts.
If you install and use React Devtools you will be able to understand the entire process of your component rendering, in the profile you can click on the blue point on the left and it will record for you what's happened with the components.
Let's see one example
I have my <App />
root component and a simple Container with an input and Counter Component inside it.
import { Container } from './Container'
const App = () => {
return (
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
height: '100vh',
}}
>
<Container />
</div>
)
}
export default App
import { useState } from 'react'
import { Input } from './components/ui/input'
import { Counter } from './Counter'
export const Container = () => {
const [inputValue, setInputValue] = useState('')
return (
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
gap: '20px',
width: '300px',
}}
>
<h1>Root Component</h1>
<Input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
style={{
width: '200px',
}}
/>
<span>
Lorem ipsum dolor sit amet,
consectetur adipisicing elit. Ipsum deleniti
eum eveniet a neque dolores,
facilis est consectetur numquam blanditiis
illum nam tenetur eius expedita laborum?
Hic praesentium inventore sunt?
</span>
<Counter />
</div>
)
}
import { useState } from 'react'
import { Button } from './components/ui/button'
export const Counter = () => {
const [count, setCount] = useState(0)
return (
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
gap: '20px',
}}
>
<span>{count}</span>
<Button
style={{
width: '100%',
}}
onClick={() => setCount(count + 1)}
>
+
</Button>
<Button
style={{
width: '100%',
}}
onClick={() => setCount(count - 1)}
>
_
</Button>
</div>
)
}
Now let's enable a feature in React dev Tools, with which we can see highlight updates when components are re-rendered.
In the first case, we'll click on the component button to increase the counter value, as you can see, only it is being re-rendered again.
It happens because in this case, we are just updating the component, every time we click on the increase button, this event handler is called onClick={() => setCount(count + 1)} , and the counter state is updated.
All the steps I explained above take place in this quick process.
Now we'll type something in our input within the Component.
As we can see, the component is being re-rendered because we are updating inputValue state every time we type something in the input, but the Counter component is being re-rendered too, it's happening because Counter is children from Container, and when the parent component is re-rendered, the children are also.
We have some resources in react to avoid this behavior in certain situations, using the memo
, but I'll talk about that in another post.
That's all for today guys! I hope you liked the content, leave your feedback.
Posted on August 27, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.