Dependency Injection in React (2)
React's useContext
is an implicit way to do dependency injection.
Components which use values from a context implicitly declare its usage of the context provider. The context provider is acted as an implicit constructor for the use of the components.
Let's say we have a Select
component that is using options context.
....
const Select = () => {
const options = useContext(optionsContext)
return <Select>
{options.map(option => <Option value={option.value}>{option.label}</Option>)}
</Select>
}
This creates the default context.
const optionsContext = createContext([{ label: 'Hello', value: 'world' }]);
So in the case that Select
is used without a context, the default context will be used. The select will only contain one option.
However, we can inject options via optionsContext.Provider
from outside.
...
const MyFilters = () => {
return (
<div>
<optionsContext.Provider value={[{ label: 'yay', value: 'yay' }]}>
<label>
hello <Select />
</label>
</optionsContext.Provider>
</div>
);
};
Now the Select
will have a different options.
Thus, depending on where the Select
is used, we can inject different options to it.
Another good thing about the useContext is that the closest context always override the further context, thus making the context API extremely flexible.
The only downside of it is the implicity of the useContext
declarations. If we can always declare that the contexts a a component is using when we are writing it, this will be a much less a problem.