React Context and Component Coupling
One of React’s more advanced features is Context. Developers say it’s advanced because it’s a double-edged sword that can lead to huge problems further down the road of a project if used for the wrong purpose.
What is it for?
React Context is specifically for coupling components. What do I mean by coupling? I mean creating a component that 100% depends on a parent component. Without the parent component, the component that requires its context should have limited functionality.
Let’s look at a simple react-native example
In this case it’s clear that the CardTextInput
component depends on the Card
component to work but because CardTextInput
doesn’t understand that dependency, the developer that is interfacing with both the Card
and CardTextInput
components is forced to build that dependency.
That just plain sucks. For more complex dependencies, things only get worse and building around these dependencies requires a lot of communication in a team to get people to really know how to wire up non-contextual components with real dependencies.
How to couple using Context
To use Context
we have to build our components with 3 important properties: contextTypes
, getChildContext
, and childContextTypes
.
getChildContext
is a function that goes on the parent component, it is run by the child component to set this.context
. This is where we set the properties we want the child component to have access to.
childContextTypes
is an object that describes what the content of getChildContext
looks like on the parent component. It does a type check much like propTypes
to make sure the context returned by getChildContext
is correct.
contextTypes
is an object that describes what part of the parent component’s context the child component needs. Think of it like a request from child to parent that also does a type check. This object is attached to the child component.
Using Context to remove complexity
Let’s use context to simplify this clear dependency.
Watch how CardTextInput
and Card
don’t need any additional wiring to work. This is awesome and what any developer would expect to see. Now all CardTextInput
will scroll to position when they receive focus.
The case against Context
So why does react advise against using Context? Because of the way shouldComponentUpdate
works.
If the Context
changes but neither props
nor state
changes with a component that is in between the two coupled components, then the coupled child component will not update. Read more about it here. It is also an experimental API which could potentially change in the future but is actively used in React Router.
What does this mean when coupling? It means your Context
should never update! That should be handled via props.