How to get multiple static contexts in new CONTEXT API in React v16.6
This is explained in the React context documentation:
You can only subscribe to a single context using this API. If you need to read more than one see Consuming Multiple Contexts.
One workaround is to use a wrapper that combines the two contexts into one and then export the wrapper. There are multiple ways to implement the wrapper, but here is one:
Contexts.js
import React from "react";
export const Context1 = React.createContext("1");
export const Context2 = React.createContext("2");
export const ContextCombined1And2 = React.createContext("3");
ProvideCombinedContext.js
import React from "react";
import { Context1, Context2, ContextCombined1And2 } from "./Contexts";
// This is a reusable piece that could be used by any component that requires both contexts.
const ProvideCombinedContext = props => {
return (
<Context1.Consumer>
{context1 => (
<Context2.Consumer>
{context2 => (
<ContextCombined1And2.Provider value={{ context1, context2 }}>
{props.children}
</ContextCombined1And2.Provider>
)}
</Context2.Consumer>
)}
</Context1.Consumer>
);
};
export default ProvideCombinedContext;
Need2Contexts.js
import React from "react";
import { ContextCombined1And2 } from "./Contexts";
import ProvideCombinedContext from "./ProvideCombinedContext";
class Need2Contexts extends React.Component {
static contextType = ContextCombined1And2;
componentDidMount() {
console.log("Context=" + JSON.stringify(this.context));
}
render() {
return "this.context=" + JSON.stringify(this.context);
}
}
const WrappedNeed2Contexts = props => {
return (
<ProvideCombinedContext>
<Need2Contexts {...props} />
</ProvideCombinedContext>
);
};
export default WrappedNeed2Contexts;
index.js
import React from "react";
import ReactDOM from "react-dom";
import { Context1, Context2 } from "./Contexts";
import Need2Contexts from "./Need2Contexts";
function App() {
return (
<div className="App">
<Context1.Provider value="value1">
<Context2.Provider value="value2">
<Need2Contexts />
</Context2.Provider>
</Context1.Provider>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
You can see this in action and play with it here: