14

TL;DR Given the following example code:

ReactDOM.render(<MyComponent prop1={someVar} />, someDomNode);

Is it possible to manually pass React context into the instance of MyComponent?

I know this sounds like a weird question given React's nature, but the use case is that I'm mixing React with Semantic UI (SUI) and this specific case is lazy-loading the contents of a SUI tooltip (the contents of the tooltip is a React component using the same code pattern as above) when the tooltip first displays. So it's not a React component being implicitly created by another React component, which seems to break context chain.

I'm wondering if I can manually keep the context chain going rather than having components that need to look for certain data in context AND props.

React version: 0.14.8

webbower
  • 756
  • 1
  • 7
  • 21

2 Answers2

18

No. Before react 0.14 there was method React.withContext, but it was removed.

However you can do it by creating HoC component with context, it would be something like:

import React from 'react';

function createContextProvider(context){
  class ContextProvider extends React.Component {
    getChildContext() {
      return context;
    }

    render() {
      return this.props.children;
    }
  }

  ContextProvider.childContextTypes = {};
  Object.keys(context).forEach(key => {
    ContextProvider.childContextTypes[key] = React.PropTypes.any.isRequired; 
  });

  return ContextProvider;
}

And use it as following:

const ContextProvider = createContextProvider(context);

ReactDOM.render(
  <ContextProvider>
    <MyComponent prop1={someVar} />
  </ContextProvider>,
  someDomNode
);
Bogdan Savluk
  • 6,274
  • 1
  • 30
  • 36
  • 1
    I suspected it was impossible to manually continue the `context` chain. The React docs and what I could interpret of the source code looked like it was impossible that way, but I wanted to make sure. I had seen a solution similar to this elsewhere. – webbower Jul 05 '16 at 21:54
  • Hey can you expand on this solution a bit, I'm not quite sure how it works, and I've run into something similar where I'm trying to manage the rendering of elements based on events but some of these elements need the ReactReduxContext (or so i believe) – steff_bdh Feb 18 '20 at 02:22
  • @steff_bdh it dynamically creates context a provider with the specific fields in it. however, this is already a legacy API, and redux is probably already using a new one. Can you create a new question with example code for issue you are trying to address? – Bogdan Savluk Feb 18 '20 at 15:12
2

In React 15 and earlier you can use ReactDOM.unstable_renderSubtreeIntoContainer instead of ReactDOM.render. The first argument is the component who's context you want to propagate (generally this)

In React 16 and later there's the "Portal" API: https://reactjs.org/docs/portals.html

tlrobinson
  • 2,812
  • 1
  • 33
  • 35