According to React doc, useMemo and useCallback help performant optimization because comparison between rendering works correctly.
In my understanding, however, whenever parent component re-renders, its child components also re-render. Since react context works with the provider, all context subscribers are under parent provider. So parent provider re-rendering probably causes child re-rendering as well.
The statement below of React doc confuses me. Anyone can explain this?
even if MyApp needs to re-render, the components calling useContext(AuthContext) won’t need to re-render
>Solution :
In my understanding, however, whenever parent component re-renders, its child components also re-render.
That’s true by default, but React.memo can be used to skip rerendering of a child if its props have not changed. So if you’re using React.memo to improve performance, you need to make sure your context value isn’t changing all the time, which would eliminate the gains from React.memo
For example, the documentation you linked has MyApp returning the following:
const MyApp = () => {
// ...
return (
<AuthContext.Provider value={contextValue}>
<Page />
</AuthContext.Provider>
);
}
Suppose that Page is implemented something like this:
import { memo } from 'react';
const Page = memo(() => {
return (
<ChildThatUsesContext />
)
})
const ChildThatUsesContext = () => {
const value = useContext(AuthContext);
// ... do stuff
}
If MyApp rerenders and the contextValue does not change, then both Page and ChildThatUsesContext can skip rendering.
If MyApp rerenders and the contextValue does change, then Page will be able to skip rendering, but ChildThatUsesContext (and all its descendants) will have to render because it called useContext(AuthContext);
So the reason to memoize contextValue is to put us in that first case more often, with all of the components skipping rendering, not just Page.