BENBUN Coder
BENBUN Coder

Reputation: 4881

Using multiple contexts in React JS

I'm a relative newbie with regards to React JS, I am trying to get my use of contexts working.

I have an app, when the entry component (App) is defined with

    <Router>
        <div className="app">
            <GlobalContextProvider>
                <Header />
                <Switch>
                    <Route path="/CodeSystem" component={PageCodeSystem} />
                    <Route path="/ValueSet" component={PageValueSet} />
                    <Route path="/RefSets" component={PageRefSets} />
                    <Route path="/" exact component={HomePage} />
                </Switch>
            </GlobalContextProvider>
        </div>
    </Router>

Further down the component tree I have a composed that uses its own context shared with its children components.

        <QueryVSContextProvider>
            <ValueSetSidebar />
            <ValueSetBody />
        </QueryVSContextProvider>

From the above, within the ValueSetBody component I have:

class ValueSetBody extends Component {
    static contextType = QueryVSContext;

    render() {
        const { bundle } = this.context;

        ...

        }
}

How could I also access the "GlobalContext" which was defined up at the App component? I want to be able to detect changes in the GlobalContext from the class component.

thanks

Upvotes: 1

Views: 1556

Answers (1)

Ken Bekov
Ken Bekov

Reputation: 14015

The easiest way is using <Context.Consumer>. For example:

class ValueSetBody extends Component {

    ...

    render() {
        <QueryVSContext.Consumer>
            {queryVSContext =>
                (<GlobalContext.Consumer>
                    {globalContext =>
                        (<div>
                            {queryVSContext.value}
                            {globalContext.value}
                            ...
                        </div>)
                    }
                </GlobalContext.Consumer>)
            }
        </QueryVSContext.Consumer>
    }
}

If you're going to use context in many places then maybe it would be better to create HOC or use render-prop technique. Example of HOC:

function connectGlobalContext(Component) {
    return function (props) {
        return <GlobalContext.Consumer>
            {context =>
                <Component {...props} globalContext={context}/>
            }
        </GlobalContext.Consumer>
    }
}

After you've created HOC you can wrap your components that need the context:

class ValueSetBody extends Component {
    ...
    render() {
        return (<div>
            {this.props.globalContext.value}
        </div>)
    }
}

export default connectGlobalContext(ValueSetBody);

Now you can create HOC for QueryVSContext the same way and use both contexts anywhere you need them.

Upvotes: 2

Related Questions