Intive Blog

Understanding the new Context API

If you have been following all the React trends in the last month, you should know that some API’s have received a redesign: Context, refs, etc. Therefore, this time, I’m going to tell you my experience of rewriting a Component using this new Context API.

But first … Do we know what Context is?

Context is another way of sharing information between parents and children (like props). You have a top component (Father) that define an object with information (Context), so any component inside of him (Children) can access that data. We could say that using props is explicit communication, while Context is implicit Communication.

When an application reaches a certain size, you will end up having more components that will also share more information between them. When this happens it is not weird to start seeing the “Prop Drilling problem”, which consists of components passing down lots of props just to give access to a component below them. This is when Context helps us! By removing that chain of props between components, we’ll end up with a more readable and understandable code. Let’s see an example.

Communication Diagram

>Via props

>Via Context

Why did React rewrite Context?

Now that we know what “Context” is, its main flaw today is how it interacts with shouldComponentUpdate.

    • shouldComponentUpdate blocks Context changes: Context changes will not propagate through a component whose shouldComponentUpdate return false. shouldComponentUpdate is a fairly common optimization in React applications.
    • Shifts complexity to userspace: developers circumvent the shouldComponentUpdate problem by using subscriptions which are largely adopted in Open Source libraries like Redux and React Broadcast. The problem is that the ownership and responsibility for a core feature (Context) have been shifted from the framework to its users.

What does this new API offer?

The React developer’s team has re-designed the way we declare a Context inside a Component from scratch and introduced new concepts that were previously not present within the framework. Let’s see a comparison between the new version and the old one.

>Old version

>New version

List of changes:

  • Removed the need for using getChildContext to set values inside a context.
  • Removed contextType and childContextTypes static definition in the parent and children (which in my opinion was the worst).
  • Added a new method React.createContext which creates a new instance of a Context and returns an object with a Provider and a Consumer.
  • The Provider component now allows you to define values inside the Context created.
  • The Consumer component currently uses the renderProp pattern inside its children.  Through that function we’ll have access to all the information that belongs to the created Context.

Let’s build something!

In 2017 I wrote a RadioGroup component with the old Context API, so my goal is to rewrite it using the new one! I chose this RadioGroup because it is one of those components that are very annoying to build in React. If you want to know why, just check this piece of code that aims to render a set of controlled radio buttons.

 

You’ll agree with me, that’s a lot of code just to manage 3 radio buttons! Let’s see how you can accomplish the same goal with the abstraction of the RadioGroup built with Context.

RadioGroup built with the new Context API

That looks so much better right? Let’s see what is happening.

As you can see I have created a new component called RadioGroup which received all the shared properties along the RadioButton. Then those properties are magically passed to every RadioButton, which can determine if they are selected or not by themselves. So, how are we going to do that? The answer is: Context.

In order to create a new Context just call to React.createContext and pass it a name.

Writing RadioGroup and RadioButtons

Following this, let’s see how to write RadioGroup and RadioButtons.

a) RadioGroup

This component is responsible for distributing the information to the RadioButtons and nothing more, it doesn’t have to render anything in particular. It does have to store inside its Context the following:

  • Name of the group for the radio buttons.
  • The callback onChange.
  • The selected radio.
  • If the group is disabled.
b) RadioButton

This component has to read from the Context defined by the RadioGroup and make some validations:

  • If the selected radio is equal to the id, then checked has to be true.
  • If the disabled or disabledGroup is true, then disabled has to be true.
  • In case value was not sent, then the value should be equal to the id.

Merging all of these, we end up with this powerful library!

I really like this new API, and I think it will be game changing in React. I invite all of you to build your own components using this awesome API. It’s really powerful. Let’s keep building stuff together!

Refs:

Emanuel Suriano

Emanuel Suriano is Web Developer at intive-FDV since August 2016. Computer Engineer graduated from Universidad de La Matanza, he is in love with Javascript and the entire ecosystem that grew up around him, passion that led him to build all kinds of things in that language: web applications, IoT, mobile applications and libraries. When he is not working, he is committed to the challenge #100DaysOfCode, whose main objective is to code at least one hour every day. Among his hobbies are: (if it wasn’t clear already) programming, playing video games and walking with his dog Lara.

Add comment