DEV Community

Michał Kardyś
Michał Kardyś

Posted on

3 3

Setup external modules with React Context

(story originally appeared at kardys.dev)

A pattern that is helpful when you use external modules in your app.

Some time ago Dan Abramov posted this tweet:
Dan Abramov's tweet

<Context.Provider value={<RenderedComponent />}>
  <Something />
</Context.Provider>
Enter fullscreen mode Exit fullscreen mode

This pattern is neither necessary nor common, yet it is useful at certain times.

What are use cases?

The pattern is helpful when external modules arise. What exactly do I mean by external module?

See, chat. Let's assume you have SPA and you want to add Intercom-like chat to your app.

Should you setup it somewhere down in your render-tree?

It is an option.

FloatingButton.jsx
//...
<Chat
    prop1={prop1}
    flag
    anotherFlag
    />

Enter fullscreen mode Exit fullscreen mode

Yet,

What if you need a change?

  • You might need it in 2+ places:
    • under a floating button
    • or when user selects 'help' section
    • so, you instantiate 2 some components 2 times?
  • You might want to keep all external configs in one place
    • to have an eye on dependencies
    • to slowly replace all externals with your internal code
    • would looking for all of these usages be simple? It might

...but there's another way

Setup external component with context

What if instead of:

FloatingButton.jsx
//...
<Chat
    prop1={prop1}
    flag
    anotherFlag
    />

HelpSection.jsx
//...
<Chat
    prop1={prop1}
    flag
    anotherFlag
    />
Enter fullscreen mode Exit fullscreen mode

you do:

ExternalModules
export const ExternalChatProvider = (props) => <Context.Provider value={<Chat
    prop1={prop1}
    flag
    anotherFlag
    />}
    {...props}
    />
export const ExternalChatConsumer = (props) => <Context.Consumer {...props}/>

Main
//...
<ExternalChatProvider>
    <SPA/>
</ExternalChatProvider>

FloatingButton
//...
<ExternalChatConsumer/>

HelpSection
//...
<ExternalChatConsumer/>

Enter fullscreen mode Exit fullscreen mode

It:

  • has single point of config
  • follows DRY rule
  • clearly signals that module is external (read: possibly unsafe)
  • rendered once

I've simplified code, but you could:

  • add memoization,
  • parametrize it,
  • etc.

This technique is useful not only for external modules, but for using shared components in general.

A word of caution: do not overuse

  • context is additional component,
  • it causes jumps in logic and
  • it is harder to read app flow with to many contexts.

How do you manage external components?

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read full post →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs