This site runs best with JavaScript enabled.

React Hooks: What's going to happen to react context?

December 17, 2018


With the cool new stuff coming to React (Hooks/Suspense), what's going to happen to the context api?

Earlier this year, the React team introduced the first official context API. I blogged about that new API and people got sufficiently and reasonably hyped.

One common complaint that I knew people were going to have when applying it practically was the fact that the context consumer is a render-prop based API. This can lead to a lot of nesting when you need to consume multiple contexts and other render-prop based APIs as well (for logic reuse). So I addressed that in the blog post by suggesting that you could combine all of the render-prop based APIs into a single function component and consume that:

1const ThemeContext = React.createContext('light')
2class ThemeProvider extends React.Component {
3 /* code */
4}
5const ThemeConsumer = ThemeContext.Consumer
6const LanguageContext = React.createContext('en')
7class LanguageProvider extends React.Component {
8 /* code */
9}
10const LanguageConsumer = LanguageContext.Consumer
11
12function AppProviders({children}) {
13 return (
14 <LanguageProvider>
15 <ThemeProvider>{children}</ThemeProvider>
16 </LanguageProvider>
17 )
18}
19
20function ThemeAndLanguageConsumer({children}) {
21 return (
22 <LanguageConsumer>
23 {language => (
24 <ThemeConsumer>{theme => children({language, theme})}</ThemeConsumer>
25 )}
26 </LanguageConsumer>
27 )
28}
29
30function App() {
31 return (
32 <AppProviders>
33 <ThemeAndLanguageConsumer>
34 {({theme, language}) => (
35 <div>
36 {theme} and {language}
37 </div>
38 )}
39 </ThemeAndLanguageConsumer>
40 </AppProviders>
41 )
42}

As much as this solution works thanks to the composability of React components, I'm still not super thrilled with it. And I'm not the only one:

We've heard feedback that adopting the new render prop API can be difficult in class components. So we've added a convenience API to > consume a context value from within a class component.β€Šβ€”β€ŠReact v16.6.0: lazy, memo and contextType

This new convenience API means that if you use a class component and you're only consuming one context, you can simply define a static property called contextType and assign it to the context you want to consume, then you can access the context via this.context. It's pretty neat and a nice trick for common cases where you only consume a single context.

I've used this convenience API and I love it. But I'm even more excited about the implications that React Hooks have for the future of React context. Let's rewrite what we have above with the upcoming (ALPHA!) useContext hook:

1const ThemeContext = React.createContext('light')
2class ThemeProvider extends React.Component {
3 /* code */
4}
5const LanguageContext = React.createContext('en')
6class LanguageProvider extends React.Component {
7 /* code */
8}
9
10function AppProviders({children}) {
11 return (
12 <LanguageProvider>
13 <ThemeProvider>{children}</ThemeProvider>
14 </LanguageProvider>
15 )
16}
17
18function App() {
19 const theme = useContext(ThemeContext)
20 const language = useContext(LanguageContext)
21 return (
22 <div>
23 {theme} and {language}
24 </div>
25 )
26}
27
28ReactDOM.render(
29 <AppProviders>
30 <App />
31 </AppProviders>,
32 document.getElementById('root'),
33)

WOWZA! As powerful as the render-prop based consumers are, this is even easier to read, understand, refactor, and maintain! And it's not just less code for less code's sake. Besides, often when we reduce the amount of code we also reduce the clarity of communication that code can give to us. But in this case, it's less code and it's easier to understand. I think that's a big win and a huge feature of the new hooks API.

Another big feature of React hooks is the fact that it's completely opt-in and backward compatible. I'm given such a huge amount of comfort knowing that Facebook can't make decisions that will cause grief to the engineers who are working on the oldest and one of the largest React codebases in the world. The fact that React has incrementally taken us to this new world of hooks is just fantastic. Thanks React team! Looking forward to the official release!

Conclusion

One of the coolest things about React is that it allows us to focus on solving real-world problems without normally having to get too close to the implementation of things. It's been a long time since I had to deal with cross-browser or performance issues with any degree of regularity. And now React is taking it even further and simplifying things so the code that I do write is simpler to read, understand refactor, and maintain. I just love that. Makes me wonder if there may be some things I could do about my code to simplify things for other people as well πŸ€”.

Until next time! Good luck! πŸ‘‹

Things to not miss:

  • Simplify React Apps with React Hooks and Suspenseβ€Šβ€”β€ŠMy new egghead course... of course!
  • Shurlanβ€Šβ€”β€ŠI WON NANOWRIMO THIS YEAR! That means that I successfully wrote 50,000 words of a novel in the month of November (for perspective, Harry Potter book 1 is 76k words). It was a wild month, and it was tons of fun. And you can read what I ended up with. It's a fantasy novel about a utopian world where things start to go bad and a 14-year-old girl is tasked with stopping a rebellion from inadvertently destroying the city. I think you'll love the characters, plot, and magic systemΒ :)
  • React 16.x Roadmapβ€Šβ€”β€ŠTl;DR: React 16.6: Suspense for Code Splitting (already shipped), React 16.7: React Hooks (~Q1 2019), React 16.8: Concurrent Mode (~Q2 2019), React 16.9: Suspense for Data Fetching (~mid 2019)
  • Modern React Workshop: Hooks & Suspenseβ€Šβ€”β€Ša recording of a livestream I did last week at PayPal. Here's the workshop repo and here's the part 2.

Discuss on Twitter β€’ Edit post on GitHub

Share article
loading relevant upcoming workshops...
Kent C. Dodds

Kent C. Dodds is a JavaScript software engineer and teacher. He's taught hundreds of thousands of people how to make the world a better place with quality software development tools and practices. He lives with his wife and four kids in Utah.