Context.Provider as HOC with memoized children - children still rerender on any state change
See original GitHub issuehere is my setup:
const Screen = withVideoPlayer(() => {
const load = useContextSelector(VideoPlayerContext, c => c.load);
console.log("Screen rerendered")
...
})
const withVideoPlayer = <P extends object>(WrappedComponent: FC<P>) => {
const ComponentWithPlayerContext = (props: P) => {
const controller = useInitVideoPlayerController();
const Memoized = useMemo(() => memo(WrappedComponent), [WrappedComponent]);
return (
<VideoPlayerContext.Provider value={controller}>
<Memoized {...props} />
</VideoPlayerContext.Provider>
);
};
return ComponentWithPlayerContext;
};
const useInitVideoPlayerController = () => {
const load = useCallback(
async (
video: IVideo | IVideoTrailer,
options?: Partial<{
autoplay: boolean;
position: number;
}>,
) => {
dispatch({ type: 'load', payload: { video, options } });
},
[],
);
...
return {
... a bunch of state properties and methods wrapped with useCallback
load,
};
}
the problem is the Screen component rerenders any time the context is changed, even though it only uses “load” method which is wrapped with useCallback without dependencies. If i remove const load = useVideoPlayer(c=>c.load)
from Screen, the rerenders don’t happen anymore.
could this be related to this? https://github.com/dai-shi/use-context-selector/issues/86
Issue Analytics
- State:
- Created a year ago
- Comments:5 (1 by maintainers)
Top Results From Across the Web
prevent child component to re-render below context provider ...
So I want to prevent my child components to rerender. I tried using React.memo() but it's still rendering whenever I set the state...
Read more >Preventing rerenders with React.memo and useContext hook.
Now any change of AppContext won't re-render ThemeContext ... Our component would still re-execute, but React wouldn't re-render the child ...
Read more >How did I re-render: Sharing State through React-Context
But, the child component that should not be functionally dependent upon the 'lifted' state will re-render when the state changes.
Read more >React components - when do children re-render?
At first glance, the answer is obvious - React children will re-render when either their props/state change or their parent component re-renders ...
Read more >React re-renders guide: everything, all at once - Developer way
There are four reasons why a component would re-render itself: state changes, parent (or children) re-renders, context changes, and hooks ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
so i assume if we used React’s own Context, it would always go to phase 2?
Yes, that is an expected behavior. React render has two phases, 1) render phase for invoking render function and b) commit phase to apply changes to DOM. What you see with console.log in the render function is 1) and what you see in useEffect is 2). It impacts on performance if your render function is computationally heavy. In such cases, you want to use
useMemo
and/orReact.memo
to avoid extra computations.