Re-rendering in react
what actually happens when the react re-render?
let’s start from the lifecycle of a react component , life cycle refers to the various stages, through which the a component in react goes,
there are three major stages through which react component goes
Mounting (adding of the component in the DOM)
Updating (updating component in case any props changes)
Unmounting (removing the component from the DOM)
we will explore how the updation/re-rendering works in the react often asked in the interviews.
when any props changes then the react create a new virtual dom (virtual means it creates in memory object of the original dom with new changed values ).
then it runs the diffing algorithm it which compares the new virtual dom with the previous dom .
React finds what exactly changed (maybe a text node, a button label, or a list item).
Only those specific changes are applied to the real DOM, not the entire UI (this makes efficient update).
Diffing algorithm
Updating the entire DOM when any props changes will only make our application slower, that’s where diffing algorithm comes into picture, it make sure that only the minimal and required changes are applied to the original DOM and it leads to the smooth user experience, improved performance.
Assumption for Diffing Algorithm
React uses a heuristic algorithm called the Diffing algorithm for reconciliation based on these assumptions:
Elements of different types will produce different trees (li,div , span etc.)
We can set which elements are static and do not need to be checked.
function App() {
return (
<div>
<h1>Hello, world!</h1>
<ul>
<li>Frontend</li>
<li>Backend</li>
</ul>
</div>
);
}
look at the above component this will be present in the memory as
const oldVDOM = {
type: 'div',
props: {
children: [
{
type: 'h1',
props: { children: 'Hello, world!' }
},
{
type: 'ul',
props: {
children: [
{ type: 'li', props: { children: 'Frontend' } },
{ type: 'li', props: { children: 'Backend' } }
]
}
}
]
}
};
let say if we change the <li>Backend</li> to <li>Full stack </li>
then new virtual dom will look like this
const newVDOM = {
type: 'div',
props: {
children: [
{
type: 'h1',
props: { children: 'Hello, world!' }
},
{
type: 'ul',
props: {
children: [
{ type: 'li', props: { children: 'Frontend' } },
{ type: 'li', props: { children: 'Full Stack' } } // changed prop here
]
}
}
]
}
};
React checks the root elements(type property of dom object) for changes and the updates depend on the types of the root elements
if the element type changes then the react will destroy the old subtree at that node and make a new sub-tree.
if the type of element is same, React then checks for attributes of both versions and then only updates the node which has changes without any changes in the tree. The component will be updated in the next lifecycle call.
Note: This is the main reason why we should always use unique keys (like id ) in the elements so that it will be easy for React to determine changes in the elements.
Limitations of diffing algorithm
If the key provided to the elements are not unique then it can lead to the unnecessary re-render.
in very deeply nested components, diffing algorithm may take time for comparison but it still faster than manual dom manipulation.