It’s more engineering, it’s no longer experimental, “and now it’s a first-class API! And it also uses RENDER PROP!

Note: you can get my latest information through newsletter. I send every email to my blog two weeks later. Subscribe to get more content in my inbox earlier! 💌

Have you heard of the Context API on the React website? If you have, are you like many people who have read the documentation on the website and are afraid to use it directly?

This search result is the first to show “Why not use Context”. No Context API is invoked. To make things more interesting, the search results section says:

If you want to make your application more stable, don’t use context. Because this is an experimental API, it may be changed in future React releases. .

So why do you use context?

Have you ever experienced the pain of trying to get state values from the bottom to the top of the React state tree? The pain is called “prop drilling” and it’s crushing. Eventually you have to pass props through components that don’t care about the data in order to send those props to components that need to care about the data. And these pains will be magnified as one moves to these components.

You can actually avoid these problems by using regular JavaScript modules. You can put this data in a separate module so that you can import or access it anytime, anywhere. However, there are problems with updating (you have to implement a method to ensure real-time updates), and server-side rendering can be problematic for singletons.

This is where state management libraries like Redux come in. Redux allows you to easily retrieve data from anywhere in the Store (state tree). All you have to do is use this thing called usage, and the magic is that your store can be accessed by any “connected” component

What if I told you that the Redux uses is using the context’s features? That’s true! The Provider component puts data into the context, and the “wire” higher-order component extracts data from the context. So, in effect, Redux does not allow your data to access…… anywhere Context is just like that!

So, why should you use context? Well, you probably already love it! Even if you don’t use context directly, your app uses it via react-redux, mobx-react, react-router, glamorous!

The Context of rebirth

So we fell in love with context, but remember the official warning that “it might be dropped in a later react version? Now the context is released! You’re going to love it!

A month ago, the React team took inspiration from RFCS repositories in Yarn, Rust, and Ember and created a new RFCS repository of their own. The first person to pull code from the repository was Andrew Clark, a member of the React core team. It was called the “new Context”. In it, Andrew describes what the new context will look like. There are some very interesting discussions going on in this warehouse. A few days later, Andrew proposed a PR for the “New Context API” to the React repository.

So what does it look like? The naked eye estimates that the new API is millions of degrees different from the previous API. This is a simple and practical example THAT I did

This is a simpler version, so you don’t have to open a separate code link:

const ThemeContext = React.createContext('light')
class ThemeProvider extends React.Component {
  state = {theme: 'light'}
  render() {
    return (
      `<ThemeContext.Provider value={this.state.theme}>`
        {this.props.children}
      `</ThemeContext.Provider>`
    )
  }
}

class App extends React.Component {
  render() {
    return (
      `<ThemeProvider>`
        `<ThemeContext.Consumer>`
          {val => `<div>`{val}`</div>`}
        `</ThemeContext.Consumer>`
      `</ThemeProvider>`
    )
  }
}
Copy the code

You may have noticed in my code example that I’m using the Render Prop Consumer component (best!). If you don’t like it this way, you can easily implement higher-level components or other content using the Context API (which is why it’s best). The latest Context API consists of three main parts:

  • React.createContextUsed to pass initial values (optionala fancy opt-out function that uses a bitmask)., returns an object containing provider and Consumer
  • The ProviderThe component takes a deeper value in the tree and accepts a prop (which can be anything) named the value. .
  • The ConsumerFunction is used anywhere after the provider and passes a function that returns JSX.

I’m very excited about this API. The React team will also remove the warning that context is an experimental API, as it is now a “first-class feature” of the framework. This means that developers will no longer worry about using context to solve prop-drilling problems in their applications, will no longer rely on Redux and will prefer React (perhaps James Kyle’s Unstated approach was what we were expecting).

What I saw recently:

I think we’ll feel less pain if we avoid prematurely and arbitrarily interrupting the Render method. But even if we feel it, we have a solid core React API to help us avoid this problem.

The Context practice

One problem I have encountered many times with the Context API (or the generic Render prop pattern) is how to combine providers and consumers. When a bunch of Render Prop components are put together in a Render method, they are nested like this:

So how do we avoid that from you? If this is a hassle, you can do it the usual way: utility functions/components. Here’s an example:

const ThemeContext = React.createContext('light')
class ThemeProvider extends React.Component {/* code */}
const ThemeConsumer = ThemeContext.Consumer
const LanguageContext = React.createContext('en')
class LanguageProvider extends React.Component {/* code */}
const LanguageConsumer = LanguageContext.Consumer

function AppProviders({children}) {
  return (
    `<LanguageProvider>`
      `<ThemeProvider>`
        {children}
      `</ThemeProvider>`
    `</LanguageProvider>`
  )
}

function ThemeAndLanguageConsumer({children}) {
  return (
    `<LanguageConsumer>`
      {language => (
        `<ThemeConsumer>`
          {theme => children({language, theme})}
        `</ThemeConsumer>`
      )}
    `</LanguageConsumer>`
  )
}

class App extends React.Component {
  render() {
    return (
      `<AppProviders>`
        `<ThemeAndLanguageConsumer>`
          {({theme, language}) => `<div>`{theme} and {language}`</div>`}
        `</ThemeAndLanguageConsumer>`
      `</AppProviders>`
    )
  }
}
Copy the code

The purpose here is to use common cases, combined with special functions/components, to make the case more engineering! Does that make sense? I hope it does 😅 I have another example here that really shows how bad nesting is and how to link it using a JMEas method called the React-Composer Utility

I should mention that I don’t want you to need to nest render props constructs in practice. At any time, you can create a simple building block, put them together, and use that component.

conclusion

As I said before, I’m very excited about this new API. The API is not currently available, but one will be included in the next React Minor release. Despite concerns, the previous API will continue to work well until the next major release. So, everyone has time to migrate. Also, don’t forget that the React team has over 50,000 React Components to maintain on Facebook, so it’s likely that a Codemod will be released in the future to automatically update most people’s code (just like the previous version).

I’m excited about what this new API has to offer. As I mentioned on Twitter recently (in response to Dan Abramov’s tweet): So much to expect! Good luck! 👍

Not to be missed:

  • react-broadcastisMichael JacksonA library that provides the same functionality as Context.Next versionWill be forReact.createContext(to eJames KyleShoutout as well as createcreate-react-contextI actually use react-broadcastIn my Advanced React classI will have to update 😅 when the new contextAPI is officially released.
  • react-fns: browser API byJared PalmerSwitch to declarative React components and HoC’s👏
  • react-composerBy:jmeasCompose render item components (which I used in the code box above)
  • react-contextual: Paul HenschelPaul Henschel’s Fluid-New Context API junior assistant

Some tweets from last week:

If you like these, be sure to subscribe to email, _ follow me on Twitter, _ buy me lunch, support me on Patreon, and share this with your friends

Also, retweet this is a great way to share this with friends:

👋 Hello! My name is Kent C. Dodds. I am a full stack engineer working at PayPal. I am the TC39 at PayPal. I am keen on the open source community. I am an instructor at Egghead. IO, Frontend Masters, and workshop. me. And I’m also a Google developer. M happily married and the father of four children. I love my family, love coding, JavaScript and React.