The Secret of the React Render Function
Distinguishing between calling the render function and actual re-rendering
I recently wrote a piece about React-Redux and React Thunk and received a lot of feedback and questions.
Most of those questions were about the performance of my approach. Everyone said that using React context will cause unnecessary re-rendering for its consumers.
I created a simple test by putting
console.log on a render function and observing it. I found something interesting — it’s not actually re-rendering, it’s just called the render function.
Confused? Let’s find out why.
The Standard React Component Will Call the Render Function Every Time Its Parents Re-Render
Let’s have a look at this simple example. This is a simple counter app. Whenever the user clicks the “Up” button, the counter will increase by one and the app component gets re-rendered.
So the question is: “Does the child component get re-rendered too?”
See, it has logged
child component re-render five times when we clicked the Up button five times and the counter increased to five.
So, does that mean the child component got re-rendered?
No, it’s not re-rendered. It’s only called the render function and hasn’t actually re-rendered. So, we need to distinguish between “re-render” and “called function render”. (In this case, the child component is a functional component so the render function is itself.)
The normal component will call the render function when its parent gets re-rendered. In this case, the app component got re-rendered because its state changed when we clicked the Up button, so it’s led to the child component calling the render function.
What React does under the hood when the render function gets called, is that it’ll recalculate the virtual DOM of that component and will compare that with the previous virtual DOM.
If it’s different, React will actually re-render the real DOM in our browser. If not, nothing on our browser changed. This is the main reason why React is fast.
I will show you how to test if the real DOM is updated or not.
1. Enable the Rendering tab in the Chrome console
2. Run your app and observe
Every DOM node getting re-rendered will flash in a green background color like this:
As you can see, on first load, the whole DOM got re-rendered, so the background green area shows on the whole page.
But, when we click the Up button, even the console log shows five times, but the child component (Hello text) is not re-rendered.
React Component Also Recalls the Render Function If setState is Called
The React component also recalls the render function if
setState is called, regardless of whether the value of state is changed or not.
Let’s have a look at this example:
See, we only set the value of the count object to one and display it. You would expect that the
console.log (‘app’) only calls once, when the value of the count changed from zero to one.
However, it actually calls every time we click the Up button. (See the console.)
The event called the render function many times, but the real DOM only updated once.
You can test it yourself with the rendering options in the debug tool, as described above.
- Render function recalls only trigger the re-rendering of the virtual DOM, this doesn't mean the real DOM will re-render.
- A state change will trigger the render function recall, regardless of whether its value changed or not.
- Choose wisely for optimization on your components. You shouldn't make use of
PureComponenteverywhere, instead, prefer to optimize for list components, and those components have heavy JS computations.
I hope you enjoyed this piece. Thanks for reading!