createContext
1 2 3 4 5 6 7 |
|
Context provides a form of dependency injection in Solid. It is used to save from needing to pass data as props through intermediate components.
This function creates a new context object that can be used with useContext and provides the Provider control flow. Default Context is used when no Provider is found above in the hierarchy.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
The value passed to provider is passed to useContext
as is. That means wrapping as a reactive expression will not work. You should pass in Signals and Stores directly instead of accessing them in the JSX.
Default value¶
createContext()
takes an optional "default value" as an argument. If useContext
is called and there is no corresponding context provider above it in the component hierarchy, then the value passed as defaultValue
is returned. However, if no defaultValue
was passed, then undefined
is returned in this case. Also, defaultValue
(or undefined
) is returned if useContext
is called inside an event callback, as it is then outside of the component hierarchy.
This has implications for TS. If no defaultValue
is passed, then it is possible that useContext()
will return undefined
, and the types reflect this.
Common issues with createContext
and useContext
¶
As described in the previous section, it is possible for useContext
to return undefined
.
Because of this, if an initial value was not passed to createContext
, the TS type signature of useContext
will indicate that the value returned might be undefined
(as mentioned above). This can be quite annoying when you want to use the context inside a component, and particulary when immediately destructuring the context. Additionally, if you use useContext
and it returns undefined
(which is often, but not always, the result of a bug), the error message thrown at runtime can be confusing.
There are two approaches to prevent these issues. One approach, which generally works well, is to wrap all uses of useContext
in a function that will explicitly throw a helpful error if the context is undefined
. This also serves to narrow the type returned, so TS doesn't complain. As an example:
1 2 3 4 5 6 7 |
|
Another (used in the example in the previous section) is provide a default value to createContext()
. In that case, useContext()
will always return a value, and therefore TS will not complain either. The pitfall with this approach is that if you unintentionally use useContext
outside of a provider, it may not be immediately apparent, because the context is still providing a valid value. Therefore, if you expect to always use useContext
within a provider, it is best to use the error based approach described above.