Alex Sidorenko AvatarAlex Sidorenko

19 Aug 2021

A Visual Guide to React Rendering - Context

This article is a 5th chapter of A Visual Guide to React Rendering

When a component consumes context, and the value of this context changes, this component re-renders. But why does Component A and Component B also re-render in this example:

The components structure is App (ContextProvider) > A > B > C

const App = () => {
// ...
return (
<AppContext.Provider value={/* ...*/}>
<ComponentA />
</AppContext.Provider>
)
}

const ComponentA = () => <ComponentB />
const ComponentB = () => <ComponentC />

Context and React rendering

From the first chapter, we know the default behavior of React rendering. When a component renders, React will recursively re-render all its children regardless of props or context. Let's remove the context from our example and see this behavior in action.

From the same chapter, we learned that to stop this recursive re-rendering, we can use memo. Let's apply memo to the initial example.

Therefore 馃憞

That React Component Right Under Your Context Provider Should Probably Use React.memo

Sophie Alpert (@sophiebits)

Context and references

In real-world applications, we often need to pass more data to the context. Sometimes this data will depend only on certain specific state variables.

We pass a and b to the provider, but the consumer component re-renders even when count updates. How can we prevent that?

Here's a hint - the text variable stores an object (a non-primitive value). And... 馃憞

All consumers that are descendants of a Provider will re-render whenever the Provider鈥檚 value prop changes

React Docs - Context Provider

When we update the count value, the App component re-renders, leading to the redeclaration of the text variable. From the second chapter, we learned the difference between primitive and non-primitive values in JavaScript. We know that {a: "lorem", b: "ipsum"} !== {a: "lorem", b: "ipsum"}. This means that on every render of the App, the context value changes even if a and b don't. And when the context value changes, the context consumer re-renders. To prevent this, we need to ensure that the text variable receives the same object reference. From the third chapter, we know that we can do this with useMemo.

Now the text variable will only change when one of the values in the useMemo dependency list changes. The count is not on the list. Therefore, when count changes, text will retain its previous reference, and the context consumer will not re-render.

Next chapter

A Visual Guide to React Rendering - DOM


Follow me on 饾晱 for short videos about Next.js

饾晱 Follow for more