Consider keeping legacy context API for non-state usages
See original GitHub issueDo you want to request a feature or report a bug? Feature request / question
According to React docs, there are 2 ways to avoid passing props through many levels:
- (New) context API
- Composition (Inversion of control)
When using the new context API, a consumer component must know, and explicitly import, a context. This raises a quite big disadvantage comparing to the legacy context API: Such component can’t be reusable with different contexts (unless making a prop only version of this component, and wrapping it with another one that uses the context directly). In fact, it means that a component can’t be “contextual” and reusable (by different contexts) at the same time.
Using composition in many cases feels wrong for solving this, quoting the docs: However, this isn’t the right choice in every case: moving more complexity higher in the tree makes those higher-level components more complicated and forces the lower-level components to be more flexible than you may want.
Example of a component I struggle to understand why it should now import a context:
import * as React from "react"
import * as propsTypes from "prop-types"
export class Link extends React.PureComponent {
static contextTypes = {
navTo: propsTypes.any
}
handleClick = (e) => {
e.preventDefault()
const {path} = this.props
this.context.navTo(path)
}
render() {
const {path, ...props} = this.props
return <a href={path} onClick={this.handleClick} {...props} />
}
}
If it was already discussed or answered, I apologize, couldn’t find any related issues.
Issue Analytics
- State:
- Created 5 years ago
- Comments:12 (6 by maintainers)

Top Related StackOverflow Question
To complement this, the explicit nature is intentional. The problem with the implicitness of the old API is that you start running into name clashes between different libraries and different parts of a large app because they share the same namespace. Kind of like with global variables.
@GBarthos Sure
I will start by mentioning that I still find the implicitly of the legacy API a bit more elegant, but that not crucial for me. After understanding where I was wrong about the new API I realized I can get the same result with it.
I had a wrong conception about where and when to use React.createContext. In short, I always used it nearby the “Providers” (where the actual context data existed), instead of nearby the “Consumers”
In my example above I have 1 “consumer” component, Link, and 1 “provider” component, App. Now, let’s say Link is a separated module, with no dependencies, and App is a top level module that depends on the Link module. At first I done this:
app module:
link module:
It is clear how I break modularity here (app depends on link and link depends on app), I think what confused me is the name “createContext”, it tricked me to always put it where the actual instance of the context is. It actually does not create a context as its name implies, but utility components to provide and consume contexts.
This is how it should be, just the opposite, link doesn’t depends on app: