1. Setting parent state for dynamic context
Firstly, in order to have a dynamic context which can be passed to the consumers, I'll use the parent's state. This ensures that I've a single source of truth going forth. For example, my parent App will look like this:
const App = () => {
const [name, setName] = useState("John");
const value = { name, setName };
return (
...
);
};
The name is stored in the state. We will pass both name and the setter function setName via context later.
2. Creating a context
Next, I created a name context like this:
// set the defaults
const NameContext = React.createContext({
name: "John",
setName: () => {}
});
Here I'm setting the defaults for name ('John') and a setName function which will be sent by the context provider to the consumer(s). These are only defaults and I'll provide their values when using the provider component in the parent App.
3. Creating a context consumer
In order to have the name switcher set the name and also showing, it should have the access to the name setter function via context. It can look something like this:
const NameSwitcher = () => {
const { name, setName } = useContext(NameContext);
return (
<label>Your name:</label><br />
<input type='text' onChange={e => setName(e.target.value)} />
<p>{name}</p>
);
};
Here I'm just setting the name to input value but you may have your own logic to set name for this.
4. Wrapping the consumer in a provider
Now I'll render my name switcher component in a NameContext.Provider and pass in the values which have to be sent via context to any level deeper. Here's how my parent App look like:
const App = () => {
const [name, setName] = useState("John");
const value = { name, setName };
return (
<Name.Provider value={value}>
<NameSwitcher />
</Name.Provider>
);
};