DEV Community

Alex Sidorenko
Alex Sidorenko

Posted on • Originally published at alexsidorenko.com

A Visual Guide to React Rendering - It Always Re-renders

When does a React component re-render? Is it when its state or props change?

React components re-render in response to parent render

Take a look at the gif above 👆

The structure of the app is: App > A > B > C.

Here is a slightly simplified code:

const App = () => {
  // state
  return (
    <ComponentA />
  )
}

const ComponentA = () => <ComponentB />
const ComponentB = () => <ComponentC />
Enter fullscreen mode Exit fullscreen mode

Components A, B, and C don't have any props or state. Yet, they still re-render when the App renders.

In normal rendering, React does not care whether "props changed" - it will render child components unconditionally just because the parent rendered!

Mark Erikson - A (Mostly) Complete Guide to React Rendering Behavior

To illustrate this point further, let's add a state to every component and track the behavior.

The tree of react components. Each has a button that updates its state.

When the state of C changes, only C renders. But when the state of B changes, both B and C render. The B renders because its state updates, and C renders because its parent renders.

When the state of A changes, A renders because of the state update, B renders because A rendered, and C renders because B rendered.


Avoiding re-renders

There are several ways to avoid unnecessary re-renders in React. In this article, I will only focus on React.memo and save other methods for future posts. If you are interested in alternatives to memo check out Dan Abramov's Before you memo().

Also please keep in mind that in this post, I only explore re-renders caused by direct state update, or parent render. I don't pass any props.

If you wrap a component in memo, it won't re-render when its parent renders.

The tree of react components. The last one wrapped in memo

Notice that C updates when its state changes, but not when the parent renders.

Lifting memo up

Let's lift memo up and see what happens.

The tree of react components. The first one wrapped in memo

The state update of components A, B, and C produces the same results as before. But notice the state update on the App. Wrapping a component with memo prevents the entire subtree of this component from re-rendering in response to parent render.

That's why you can hear advice like this:

What about adjacent components?

The tree of react components. One of the adjacent components wrapped in memo.

The same rules apply to adjacent components. The component with memo doesn't re-render in response to parent render, and therefore, prevents its entire subtree from re-rendering.


Should I memo everything?

If memo has such a great effect on performance, does it make sense to wrap everything with it? Well, not really. But this is a topic for another day. If you are interested, read Fix the slow render before you fix the re-render by Kent C. Dodds.


To be continued...

There is more to the rendering mechanism of React. To make the article simple, I purposefully left out things like passing props, context, DOM updates, and additional techniques to avoid re-rendering. I will write a separate post on each of these topics.


Originally published at alexsidorenko.com

Top comments (0)