What's New in React 16.6 By Example

What's New in React 16.6 By Example

The release of React's 16.6 minor version bump came with some new React tools for React developers. Since it's a only a minor version, React teams should feel comfortable upgrading because there aren't any breaking changes -- only new features and bugfixes.

Context Type

This is, in my opinion, the most exciting addition in 16.6.

The context API had its stable release in 16.3, but one feature it sacrificed was removing this.context as a way to interact with context. This feature has been missed among developers who are uncertain if render props are the right direction to go in.

With 16.6, you can now declare a contextType in a component and then access this.context to get the context from your provider without having to pass down render props.

It's important to note that the context value is from the closest matching Provider above your current component in the tree.

So you'll still have to wrap your entire app (or at least your component) in your Provider, but then that provider is easily accessed with this.context.

For example, if you have a simple counter that's using state in a context provider, you'd previously have to do something like this to render it:

const VoteContext = React.createContext();

const VoteCount extends Component {
  render() {
    return (    
      <VoteContext.Consumer>
        {context => (
          <div>{context.state.count}</div>
        )}
      </VoteContext.Consumer>
    )
  }
}

Now, you can either add static contextType or add .contextType if you aren't using static class fields.

const VoteContext = React.createContext();

class VoteCount extends Component {
  static contextType = VoteContext
  render() {
   return (
     <div>{this.context.state.count}</div>
   )
  }
}

If you want to see an example in action, I created this CodeSandbox to demonstrate how to use contextType.

Memo

Although the name of this new API has been met with mixed feedback, the Memo API is essentially a wrapper / higher-order component that provides the benefits of a Pure Component to function components.

There's been plenty written about the benefits of Pure Components,. The short version is that Pure Components can provide a performance boost by preventing a component from re-rendering if the props don't change. But be warned, if you're using deeply nested data, Pure Components only do a shallow check for performance reasons, so try to limit it to simple data or use immutable objects..

Anyway, enough theory, let's see it in an example.

Let's say you have a "dumb" component that just displays a user's name and avatar in the top right of a dashboard. You have a simple functional component because it doesn't need to have state, it just needs to render out its props:

function UserInfo(props) {
  const { name, avatar } = props;
  return (
    <div>
      <img src={avatar} alt={`${name}'s avatar`} />
      <span>{name}</span>
    </div>
  )
}

Now let's say you have this component and a "search" input component both in the header of your site.

Each time your user types into the input and changes the input of your header, UserInfo is going to actually trigger a re-render, even if the props for the UserInfo component don't change.

If you're already using a full React component, it'd be easy to switch over to React.PureComponent and remove this unnecessary render. But now with Memo, you can leverage that same performance boost with your functional components:

const UserInfoMemo = React.memo((props) => {
  const { name, avatar } = props;

  return (
    <div className="user-info">
      <img src={avatar} alt={`${name}'s avatar`} />
      <span>{name}</span>
    </div>
  );
});

I created this quick CodeSandbox to demonstrate the differences. Type into the search input and notice how UserInfoNormal is actually re-rendering on every keystroke, even though the props aren't changing. Compare that to UserInfoMemo, which is only doing one initial render and not re-rendering when the main App component's state is changing.

React.lazy code-splitting