DEV Community

Re-rendering in React

therealnrf on October 02, 2021

I recently saw the following tweet from @_georgemoller which posed an interesting question related to component re-rendering in React: // Det...
Collapse
 
marzelin profile image
Marc Ziel • Edited

Every time the state of a component changes, that component and all of its children are re-rendered.

This isn't entirely true because React compares each child and bails out of re-rendering if a child is strictly equal.

function App() {
  const [count, setCount] = useState(0);
  return (
    <div>
      Count is: { count }
      { someComponent }
      <button onClick={() => setCount(count => ++count)}>
        Increase count
      </button>
    </div>
  );
}

const someComponent = <SomeComponent />;

function SomeComponent() {
  return <div>I'm some component</div>;
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
therealnrf profile image
therealnrf

That is actually not true as you can see in the examples. This behavior can be prevented though either by using memoization or the shouldComponentUpdate method (assuming the state can't be moved to another component of course).

The shouldComponentUpdate method returns true by default. This is why the default behavior of React is to re-render all child components on state change.

Collapse
 
marzelin profile image
Marc Ziel

Not true, huh?

I've provided an example code, have you even checked it? Does SomeComponent re-renders when you click the button? So annoying...

Thread Thread
 
therealnrf profile image
therealnrf

I stand corrected. But can I ask, why are you re-assigning the component to a variable and then using that variable to render the component? Because this seems to be why SomeComponent is not re-rendering.

It does re-render when you plug it in directly with <SomeComponent /> even though its still not changing when count updates.

Thread Thread
 
marzelin profile image
Marc Ziel

I'm not re-assigning anything. someComponent is a React element and <SomeComponent/> is a function call that returns a React element. These are two different things from JavaScript standpoint.

If you have A = () => ({}) then A() !== A() but when a = A() then a === a. That's the gist of it.

Collapse
 
rzs401 profile image
Richard Smith

Thanks for this post, really helpful.

Collapse
 
therealnrf profile image
therealnrf

Appreciate your feedback.

Collapse
 
jijithnair profile image
Jij

This is not true i think. I believe you are talking about 're evaluation' and not 're rendering'. Here the SomeComponent is indeed re evaluated as mentioned in the post,but it is not re rendered, as React sees no new changes to the element that requires a DOM update.

Collapse
 
theodorusclarence profile image
Theodorus Clarence

Great post!

Collapse
 
detoner777 profile image
Alexey Lysenko

And we also can use React.memo() for prevent unnecessary rerenders.

Collapse
 
therealnrf profile image
therealnrf

Absolutely. But you'd have to memoize every child component. In the case where the state lives in the root component (like in the original question), you'll have to memoize every component of the app! 😄