I'm using the new context API of react (v16.6.0 or higher) by declaring the public static contextType inside the component that consumes the context.
This is working fine as long as the component that declares the Provider does not directly use a component that consumes the context in it's render() method.
Example:
ParentWithContext
This is the component that creates and provides the context.
export const SomeContext = React.createContext({
someValue: false
});
export default class ParentWithContext extends Component {
public render(){
const contextValue = {someValue: true};
return (
<SomeContext.Provider value={contextValue}>
<ChildOne />
{this.props.children}
</SomeContext.Provider>
);
}
}
Notice that this component uses ChildOne component (s. right below) in it's render() method.
ChildOne and ChildTwo
These two components simply consume the above context and display it.
export default class ChildOne extends Component {
public static contextType = SomeContext;
public render(){
return (
<div>
{`Context of ChildOne: ${this.context.someValue}`}
</div>
);
}
}
export default class ChildTwo extends Component {
public static contextType = SomeContext;
public render(){
return (
<div>
{`Context of ChildTwo: ${this.context.someValue}`}
</div>
);
}
}
index.tsx
class App extends Component {
render() {
return (
<ParentWithContext>
<ChildTwo />
<ChildOne />
</ParentWithContext>
);
}
}
Running this example will produce following lines:
Context of ChildOne: undefined
Context of ChildTwo: true
Context of ChildOne: undefined
So ChildTwo seems to receive the correct information from this.context, while ChildOne receives nothing.
Now comes the weird part (to me): When you remove the <ChildOne/> from ParentWithContext it suddenly works for both ChildOne and ChildTwo
New ParentWithContext
export default class ParentWithContext extends Component {
public render(){
const contextValue = {someValue: true};
return (
<SomeContext.Provider value={contextValue}>
{this.props.children}
</SomeContext.Provider>
);
}
}
New HTML output
Context of ChildTwo: true
Context of ChildOne: true
Question
Why is the context API (>=v16.6) not working (using static contextType) when the Provider component directly uses a child component that consumes the context in it's render() function? Is this a bug or a known limitation? Did I miss something?
Additonal information
Using <SomeContext.Consumer> will work as expected.
export default class ChildOne extends Component {
public render(){
return (
<SomeContext.Consumer>
{context =>
<div>
{`Context of ChildOne: ${context.someValue}`}
</div>
}
</SomeContext.Consumer>
);
}
}
Of course it's not a solution for this issue but might be a useful information.
Hi @Flaneder. I think your problem is related to import statements order. If you print out SomeContext value for ChildOne you'll see undefined:

But the same print for ChildTwo will be correct:

I think it happens because you import ChildOne before actuall context definition code:

The easiest way to fix you problem is just declare context object in separate file. I updated your example here.
That's something I would've never thought of..
Most helpful comment
Hi @Flaneder. I think your problem is related to import statements order. If you print out
SomeContextvalue forChildOneyou'll seeundefined:But the same print for
ChildTwowill be correct:I think it happens because you import
ChildOnebefore actuall context definition code:The easiest way to fix you problem is just declare context object in separate file. I updated your example here.