Post

What's New in React 16.6

Draft updated on Invalid Date
Default avatar

By Austin Roy

What's New in React 16.6

This tutorial is out of date and no longer maintained.

Introduction

React version 16.6 is out and it comes packed with some useful new features that are very much worth getting excited about. It’s a minor release with major features focused on performance optimization. The main new features include:

  • React.memo()
  • React.lazy()
  • static contextType()
  • static getDerivedStateFromError()
  • a number of deprecations in StrictMode

Let’s take a look into what each of these features adds to React.

React.memo()

React.memo() is the functional component solution to React.PureComponent as used in class components. It’s a higher order component that is wrapped around functional components to create memoized components.

We’ve written up a full tutorial on React.memo() here: React.memo() for Functional Components Rendering Control

What are memoized components? To understand this, we’ll have to look at the definition of memoization, which is an optimization technique that stores the results of expensive function calls and returns these cached results in case similar inputs are provided. Hence the name memo.

The result is a component that only re-renders when it’s props change, acting kind of like shouldComponentUpdate().

Using memo()

Memo is applied by wrapping a component inside React.memo() as shown below:

const MemoizedComponent = React.memo(function MyComponent(props) {
  // only re-renders if props change
});

// for arrow functions
const OtherMemoized = React.memo(props => {
  return <div> Memoized Component </div>
}

You may also wrap an existing component to memoize it.

const MyComponent = props => <div> This is memorable!! </div>

const Memoized = React.memo(MyComponent)

Note that server side rendering for memo is still pending.

To dive deeper into memo check out this article here which looks at more use cases and gives an example.

React.lazy() and Suspense

Code-splitting allows us to lazy-load our imports, which means we only import them when they are being used hence increasing the overall speed of our applications. These are referred to as dynamic imports.

React.lazy()

React.lazy() allows us to render dynamic imports as regular components. It takes a function that must call a dynamic import(). This must return a Promise which resolves to a module with a default export containing a React component.

Without React.lazy in < React 16.6:

import OtherComponent from './OtherComponent';

function MyComponent() {
  return (
    <div>
      <OtherComponent />
    </div>
  );
}

With React.lazy in React 16.6:

const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <div>
      <OtherComponent />
    </div>
  );
}

Notice all we have to do is update the import statement! Very easy to implement and similar to how react-loadable does it.

React Suspense

In case MyComponent renders before our dynamic import, we should show some fallback content to act as a placeholder as we wait for it to load, such as a loader. This can be achieved using the higher order Suspense component.

Suspense takes a prop, fallback, which accepts React elements to be rendered while loading dynamic imports. And a single Suspense component can handle several dynamic imports.

If we have an app that is lazy loading components as shown below, if either of the components (OtherComponent or AnotherComponent) fails to load, this will break the app.

const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));

function MyComponent() {
  return (
    <div>
       <section>
         <OtherComponent />
         <AnotherComponent />
       </section>
    </div>
  );
}

We can prevent this by introducing Suspense to show a fallback loader as long as either of these components have not yet loaded as shown below.

const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <section>
          <OtherComponent />
          <AnotherComponent />
        </section>
      </Suspense>
    </div>
  );
}

static contextType

The official Context API was introduced in React 16.3 and in a bid to ease usage in class components, contextType has now been added to classes. This property can be assigned a Context object created by React.createContext(). It lets you consume the value of that Context object in your class using this.context and this can be referenced in any lifecycle method.

class ScotchClass extends React.Component {
  componentDidMount() {
    let value = this.context;
    // perform a side-effect at mount using the value of MyContext 
  }
  componentDidUpdate() {
    let value = this.context;
    // ...
  }
  componentWillUnmount() {
    let value = this.context;
    // ...
  }
  render() {
    let value = this.context;
    // render something based on the value of MyContext
  }
}
ScotchClass.contextType = ScotchContext;

Important to note, this method only allows you to consume one context.

static getDerivedStateFromError()

Introduced in React 16.3, error boundaries allow us to catch errors early and render fallback UI and prevent the app from crashing. However, the API hadn’t provided a method of handling errors that occur before rendering. In comes the static method getDerivedStateFromError(). This lifecycle is invoked after an error has been thrown by a descendant component. It receives the error that was thrown as a parameter and should return a value to update state providing a method to handle the error.

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children;
  }
}

getDerivedStateFromError() is called during the “render” phase, so side-effects are not permitted. For those use cases, use componentDidCatch() instead.

Deprecations in StrictMode

Yet another feature introduced in React 16.3, StrictMode is a higher order component that identifies potential problems in an application and provides warnings for them. In React 16.6 two more API’s have been added to the list of deprecated APIs and will fire warnings in StrictMode. These are:

  • ReactDOM.findDOMNode() - This API is often misunderstood and most uses of it are unnecessary. It can also be surprisingly slow in React 16.

  • Legacy Context using contextTypes and getChildContext - Legacy context makes React slightly slower and bigger than it needs to be. Upgrading to the new Context API is encouraged and the addition of contextType aims to make this easier.

Conclusion

React 16.6 has some pretty big additions for a minor update and aims to help developers create high performance applications that are stable, light and fast. It shows a significant step forward for React as the library continues to grow. It’s exciting to see what else the future holds for React. Read more about this release on the React blog.

Even with all the great things 16.6 has, it’s looking like 16.7 is going to be even greater!

https://twitter.com/sophiebits/status/1055127361367076864

See you then!

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Austin Roy

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel