Context is "just" a prop with special behavior, like children or key. It implicitly propagates from elements to their children, unless it is explicitly overridden.
Context can be provided as a prop (to elements) or via the children object's withContext method. Context can be consumed as a prop (to components) or by using a function in children.
This component:
const Container = ({ children }) => (
<section>
<Header>
<h1>Hello, World</h1>
<Nav />
</Header>
{children}
<Footer/>
</section>
)is equivalent to:
const Container = ({ children, context }) => (
<section>
<Header context={context}>
<h1>Hello, World</h1>
{(headerContext) => <Nav context={headerContext} />}
</Header>
{children.withContext(context)}
<Footer context={context}/>
</section>
)Note that HTML elements and text nodes do not interact with context.
Context is an object with the following methods:
update: create a new context with an updated value
context.update(
key: string | symbol,
update: (previousValue) => nextValue
) => Contextget: read a value from context, or get its default value
context.get(
key: string | symbol,
defaultValue?: any
) => any
Context can also be consumed via a `useContext` hook:
```js
const value = useContext(key, defaultValue)Context can be provided to elements via the context prop.
<Foo context={context}/>If an element is not explicitly provided a context prop, it will receive the context its parent element passes to its children.
Passing a non-Context value as a context prop is an error.
Children is an object with the following methods:
withContext: create a new children object with an updated context
children.withContext(Context) => ChildrenCalling withContext with a non-Context value is an error.
Regardless of what type of value is passed as the children prop, the component will always receive an opaque Children object.
If a function is used in children, that function is called with the parent context as its argument:
<Container>
{(context) => <Foo value={context.use(key)} />}
</Container>function createContext (defaultValue) {
const key = Symbol()
// <Context.Provider value={value}>{...}</Provider>
const Provider = ({ value, children, context }) =>
children.withContext(context.update(key, () => value))
// <Context.Consumer render={(value) => ...} />
const Consumer = ({ render, context }) =>
render(context.get(key, defaultValue))
// const value = Context.use()
function use () {
return useContext(key, defaultValue)
}
return { use, Provider, Consumer }
}