In the tutorial of React context, I saw this code :
<MyContext.Consumer>
{value => /* render something based on the context value */}
</MyContext.Consumer>
Then I get so confused, value => /* render something based on the context value */
this part like value => <h1>Hello, {value}</h1>
is a function right? Why we put a function here instead of the result of this function here? Like
<MyContext.Consumer>
{<h1>Hello, {value}</h1>}
</MyContext.Consumer>
In other function components we do things like:
function Welcome(props) {
return <h1>Hello, {props.title}</h1>;
}
We put a final value kind of like the result of a function inside the {} right? But why we just put a function in the Context.Consumer instead of the result of the function? And how and when does this function get executed? or why we don't write it like:
<MyContext.Consumer>
{(value =><h1>Hello, {value}</h1>)()}
</MyContext.Consumer>
? Thank you so much!
Because <MyContext.Consumer>
is actually a component itself and it has to pass the context
somehow to your child component. That's exactly why you pass it a function:
{value => /* render something based on the context value */}
value
here is the context and the body of the function uses this context to return a ReactNode
(or in other words your desired representation/component). This technique is called render props. <MyContext.Consumer>
will receive the function you pass it as a property named children
and will call it inside its logic with the most current version of the context to render your desired component.
Somewhere inside MyContext.Consumer
:
[this.]props.children(context);
which will actually resolve to a ReactNode
, as already noted.
In your case, if you have:
<MyContext.Consumer>
{<h1>Hello, {value}</h1>}
</MyContext.Consumer>
where is this value
coming from?
So, to recap:
Let's say we have the following consumer and it holds a value for context of Harry
:
<MyContext.Consumer>
{context => <h1>Hello, {context}</h1>}
</MyContext.Consumer>
The function context => <h1>Hello, {context}</h1>
will be passed to the MyContext.Consumer
component. The consumer component will call it by passing to it the most current value of the context(in our case it is Harry
) and then return the result. In the end, it will be like you simply have return <h1>Hello, Harry</h1>
. That simple.
The function can actually contain other components itself. For example:
<MyContext.Consumer>
{context => <Component2 contextValue={context} />}
</MyContext.Consumer>
will render the Component2
component with the context passed to it as a property contextValue
.
It's easier to wrap your head around it if you just consider your components as simple functions receiving parameters that they depend on(which is actually exactly how things work). Same goes for the Consumer
component. It's whole purpose is to receive your component(a function) and pass to it the current context so it can render the proper output and return the result.
Note that this usage is related to functional components only and in the case you're not utilizing react hooks.