8

I have a two components Parent and Child and I want to export a context from Parent to Child but this causes circular dependency.

Consider, for example, Parent.js to be

import {Child} from './Child.js';

export const MyContext = React.createContext();

const Parent = () => {
    return <MyContext.Provider><Child /></MyContext.Provider>;
}

and Child.js as

import {MyContext} from 'Parent';

const Child = () => {
    const myContext = useContext(MyContext);
    return <>{myContext}</>;
}

I can pass this as props but if there are multiple level of nesting, it would be difficult. A possible solution I can think of is using another file called contexts.js and have all my contexts exported from there.

Is there a better way to do this?

Govinda Totla
  • 576
  • 6
  • 19

2 Answers2

9

Put your context in it's own file, .e.g Context.js. Then both Parent.js and Child.js can import it.

thedude
  • 9,388
  • 1
  • 29
  • 30
  • Yeah that's what I came up with as I mentioned. I was just looking if there is a better way developers usually use as this probably seems to be a case many people should have encountered. – Govinda Totla Nov 17 '20 at 13:48
  • Chatted with coworkers - This seems to be the best solution! – Simon Jun 02 '23 at 11:21
2

Typically, rather than making the child a dependency of the parent, you loosely couple your context provider component from its children by making use of props.children.

Parent.js:

export const MyContext = React.createContext();

const Parent = ({ children }) => {
    return <MyContext.Provider>{children}</MyContext.Provider>;
};

export default Parent;

Child.js:

import { MyContext } from './Parent';

const Child = () => {
    const myContext = useContext(MyContext);
    return <>{myContext}</>;
};

export default Child;

Then you populate props.children with <Child /> when you create your virtual DOM:

import Parent from './Parent';
import Child from './Child';

const App = () => {
    return <Parent><Child /></Parent>;
};

...
Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
  • This only works in simple cases. You can't expect literally every component to be placed into App? – pbuzz007 Nov 25 '21 at 20:01
  • @pbuzz007 you're being a bit literal, it's just the simplest example I can provide. `` can be deeply nested JSX anywhere inside `...`, which means any number of components can exist between them. And no, `Parent` doesn't have to go in `App` either. – Patrick Roberts Nov 26 '21 at 00:45