I would like to set the context at runtime after some networking call is plete (only then do I know the value which needs to be accessible throughout my app), but I don't know how to persist this value.
I can update the context value like so:
<NetworkVersion.Provider value={{version: this.state.version}}>
where I can use the state of the ponent. This approach has been taken from the official React docs.
but I was surprised to find out that other Consumers of this Provider get the default value (an empty object) which was initialised in the React.createContext() call. Is there a way to update the Context at runtime and keep that value for the lifetime of the app?
I would like to set the context at runtime after some networking call is plete (only then do I know the value which needs to be accessible throughout my app), but I don't know how to persist this value.
I can update the context value like so:
<NetworkVersion.Provider value={{version: this.state.version}}>
where I can use the state of the ponent. This approach has been taken from the official React docs.
but I was surprised to find out that other Consumers of this Provider get the default value (an empty object) which was initialised in the React.createContext() call. Is there a way to update the Context at runtime and keep that value for the lifetime of the app?
Share Improve this question edited Apr 19, 2018 at 15:05 dentemm asked Apr 19, 2018 at 14:57 dentemmdentemm 6,3794 gold badges33 silver badges44 bronze badges2 Answers
Reset to default 7Make sure your Context Consumer is a child of the associated Provider, otherwise it will just get the default value. See https://reactjs/docs/context.html#consumer
You'd also be better to pass a primitive value - i.e.
<NetworkVersion.Provider value={this.state.version}>
or you may get unnecessary re-renders. See https://reactjs/docs/context.html#caveats
A consumer must be a child of the provider to get the context. If it is impossible to make your consumer be a child of the provider, make a mon parent be the provider and add a callback to the context to give consumers a possibility to change the context.
const NetworkVersion = React.createContext({
version: null,
setVersion: version => {}
});
class Parent extends React.Component {
state = {
networkContext: {
version: null,
setVersion: version => this.setState({
networkContext: {...this.stateworkContext, version}
})
}
};
render() {
return <NetworkVersion.Provider value={this.stateworkContext}>
<VersionGetter/>
<VersionSetter/>
</NetworkVersion.Provider>;
}
}
function VersionGetter() {
return <NetworkVersion.Consumer>
{networkContext => (
<div>Version: {networkContext.version}</div>
)}
</NetworkVersion.Consumer>;
}
function VersionSetter() {
return <NetworkVersion.Consumer>
{networkContext => (
<div>
<button onClick={() => networkContext.setVersion('1.0')}>Set version 1</button>
<button onClick={() => networkContext.setVersion('2.0')}>Set version 2</button>
</div>
)}
</NetworkVersion.Consumer>;
}
ReactDOM.render(<Parent/>, document.body);
<script src="https://cdn.jsdelivr/npm/[email protected]/umd/react.production.min.js"></script>
<script src="https://cdn.jsdelivr/npm/[email protected]/umd/react-dom.production.min.js"></script>