Skip to main content

prop-drilling-vs-context

Mid Child here, empty shell, passing stuff
Deep child

Normal prop drilling. Everything re-renders.


Top level, only holds context, and renders one memo'ed Page
Page (Mid Child here), empty shell
Deep child
App (top-level)
└─ Context.Provider (state here)
└─ Page/Layout (React.memo, no props)
├─ Subscriber1 (uses context)
├─ Subscriber2 (uses context)
└─ StaticComponent (doesn't rerender)


Top level Parent, holds context and renders Layout
Layout here
Sidebar here
Content here
Deep child
App
└─ ThemeContext.Provider
└─ Layout (React.memo, static slots)
├─ Sidebar (heavy, never re-renders)
├─ Content (heavy, never re-renders)
└─ DeepChild (subscribes to context)

Page, renders <Layout sidebar={} content={} />
Layout here ---
Side bar here
Content here
Deep child

Layout component
Sidebar
Content
Value:

Providers here, two diferent contexts
Layout component
Sidebar
Content
DeepChild 1
Value:
DeepChild 2
Data: 0

Page = <contextProviders /> + <Layout />
Layout component
Sidebar
Content
DeepChild 1
Value:
DeepChild 2
Data: 0

Before (Context4 or 3) - we had context provider's state right in the parent, where it renders PageMemo.

Now context state is within <ContextProvider> layers. Context state is isolated using the Wrap state around children pattern.
Now memoization isn't needed, and it's okay for the central component to have props. The paren't is never re-rendering anyway.

<ContextProvider>
<Layout heavyContent={content} >
</ContextProvider>

I could also do this, if there's only one component slot

<ContextProvider>
<DashboardLayout>
<Content />
</DashboardLayout>
</ContextProvider>

or

<DashboardLayout sidebar={<Sidebar />}>
<Content />
</DashboardLayout>