Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

React 16 Release: What's New?

DZone's Guide to

React 16 Release: What's New?

In this article, we'll highlight the most notable additions to ReactJS 16 and dabble into the architecture on which it runs.

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

ReactJS is a JavaScript library, built and maintained by Facebook. At the time of writing, ReactJS has over 78,000 stars on GitHub. And many web platforms such as Twitter, Airbnb, Lyft, Dropbox, Pinterest, Whatsapp, and Instagram use ReactJS to build their user interfaces. The ReactJS  developer community is very robust. In fact, the community is so robust that when Facebook decided to implement the BSD+ Patents license, there was a public outcry from the community. The complaints from developers were on every other blog and forum as well as at meetups and conferences. Developers and software shops around the world are pretty excited and relieved that ReactJS  has been re-licensed under the MIT license.

ReactJS 16 was announced to the world on September 26, 2017. Facebook has been working on releasing this new version for a while now. It's great that there is a new release, bu tReactJS  16 is a very special release. What's exciting about this new ReactJS  release is the fact that it was entirely rewritten from scratch while ensuring that the public API remains unchanged. This major release brings a lot of new features, deprecations, and changes.

ReactJS API-Compatible Rewrite: Why?

Questions have been flying around as to why Facebook decided to rewrite the internals of ReactJS while keeping the public API essentially unchanged. Facebook has been working on React Fiber, which is a reimplementation of ReactJS's core algorithm for about two years now. The goal of React Fiber is to enable incremental rendering - the ability to split rendering work into chunks and spread it out over multiple frames. In addition, the ability to pause, abort, or reuse work as new updates come in and the ability to assign priority to different types of updates. There are many reasons as to why it was rewritten but I'll highlight a few reasons.

  1. ReactJS needed a way to support asynchronous rendering. The current architecture couldn't have handled this addition so it needed to be re-designed from the ground up.
  2. Support for graceful and efficient error handling using error boundaries in ReactJS. It was difficult to add this frequently-demanded feature to the previously existing ReactJS architecture, so it needed to be re-designed from the ground up.
  3. The need for a new foundation that is immensely extensible and powerful enough to accommodate new idea implementation going forward. Furthermore, the support for longstanding features such as having fragments, returning text from render, unification of the scheduling of different subtrees and simple, non-complex ways to write custom renderers for ReactJS.

React Fiber

Let's talk a bit about React Fiber. As I mentioned earlier, React Fiber has been in development for a while. And there was a website made specially just to track the progress of React Fiber; isfiberreadyyet.com.

React Fiber is a complete, backward compatible rewrite of the ReactJS core which enables sophisticated scheduling of rendering work. It is a reimplementation of ReactJS's core algorithm. The goal of React Fiber is to increase its suitability for app development in sections like gestures, animation, and layouts. One key feature is the support for incremental rendering. Incremental rendering is the ability to split the rendering process into chunks and spread it out over multiple frames.

React Fiber is a reimplementation of a stack frame specialized for ReactJS components. Each fiber can be thought of as a virtual stack frame where information from the frame is preserved in memory on the heap, and because the info is saved on the heap, you can control and play with the data structures and process the relevant information as needed.

React Fiber allows smooth rendering of the UI by pausing once in a while and checking for more important updates rather than waiting for all the changes to be propagated throughout the entirety of the component tree before updating the UI. The task scheduling ability of React Fiber makes this possible.

In ReactJS, we have two important players: the Reconciler and the Renderer. The Renderer is a pluggable section of ReactJS that allows rendering of the UI to happen across and outside the DOM. It was originally created for the DOM but was later adapted to support native platforms. ReactJS has the ReactJS DOM Renderer - renders ReactJS components to the DOM, ReactJS Native Renderer - renders ReactJS components to native views, and the ReactJS Test Renderer - renders ReactJS components to JSON trees.

The Reconciler is used by the renderer to perform updates to the DOM. Whenever a component updates, be it mounting, unmounting or any form of update, the reconciler (known as the stack reconciler) processes the component tree from top to bottom synchronously in a single pass, checks for changes in the tree, then passes on these changes to the renderer. In previous versions of ReactJS, the reconciler did not have the ability to pause work, thus making performance suboptimal when deep updates occur and the CPU time is limited.

With React Fiber, the new reconciler has the ability to do the following:

  • Split interruptible work into chunks.
  • Pause work and come back to it later.
  • Reuse previously completed work.
  • And abort work.

Note: Work is the result of an update. Updates are computations performed during the traversal of the component trees.

Check out more information on Reconciliation and the React Fiber Architecture.

ReactJS 16 Features

Apart from the fact that ReactJS 16 runs on the new engine, React Fiber, ReactJS 16 ships with some new features.

  • Error handling using Error boundaries: In ReactJS 16, the error handling has been greatly improved. Before now, ReactJS applications broke whenever a runtime error occurred and required a page refresh to recover from the broken state. The component is unmounted each time any error is thrown in the constructor, render method and lifecycle methods. In ReactJS 16, error boundaries have been introduced to capture errors and display a fallback UI instead of unmounting the component every time. Error boundaries are simply ReactJS components that catch JavaScript errors anywhere in a component and child trees, log those errors, and display a fallback UI. It is important to know that error boundaries catch errors thrown in the constructor, render and lifecycle methods. The new lifecycle hook method that makes a class component an error boundary is componentDidCatch(error, info). This method works like a try/catch block for components. Create an error boundary component once and call it everywhere it's needed in your application.
     class ErrorBoundary extends React.Component {
        constructor(props) {
          super(props);
          this.state = { hasError: false };
        }
    
        componentDidCatch(error, info) {
          // Display fallback UI
          this.setState({ hasError: true });
          // You can also log the error to an error reporting service
          logErrorToMyService(error, info);
        }
    
        render() {
          if (this.state.hasError) {
            // You can render any custom fallback UI
            return <h1>Something went wrong.</h1>;
          }
          return this.props.children;
        }
      }
  • Support for Defining Custom DOM Attributes: Before now, if you used a custom DOM attribute, ReactJS would skip it. In ReactJS 16, unknown attributes will be passed onto the DOM. A typical example is shown below:
      <div alien="skullIsland" />
    
      // will be displayed in ReactJS 15 as:
      <div />
  <div alien="skullIsland" />

  // will be displayed in ReactJS 16 as:
  <div alien="skullIsland" />

Note: Using the canonical ReactJS naming for known attributes remains the same.

  • Fragments and Strings as new render return types: In ReactJS 16, you can now return an array of multiple elements from a component's render method.
    render() {
        // No need to wrap items in an extra element!
        return [
          // Don't forget the keys :)
          <p key="first">ReactJS</li>,
          <span key="second">PreactJS</li>,
          <span> key="third">VueJS</li>
        ];
      }
    Returning arrays
     render() {
        return 'Boss, I just returned a string. Can you believe it? ReactJS 16  is dope!';
      }
    Returning a string
  • Portals: This is a concept that allows you to render children into a DOM node that exists outside of the hierarchy of the parent component. In layman's terms, it simply means a child can be inserted into a different location in the DOM via Portals. For example, your app has a section component with a paragraph element as its child. Portals can be used to make the paragraph child element break out of its container.
     ReactDOM.createPortal(child, container); 
    Render the child into the container DOM node
      render() {
        return ReactDOM.createPortal(
          this.props.children,
          domNode,
        );
      }
    A typical example
  • Improved server-side rendering: The server renderer was completely rewritten in ReactJS 16 to be very fast. In addition, server-side rendering in ReactJS 16 is about three times faster than ReactJS 15 because the server renderer supports streaming. This makes the sending of data from the server to the client faster than usual. In ReactJS 16, there are two different methods for rendering on the client side, render() and hydrate(). render() as we already know for rendering content solely on the client side, hydrate() for rendering on top of server-side rendered markup. Furthermore, ReactJS 16 is better at hydrating server-rendered HTML once it reaches the client. It no longer requires the initial render to exactly match the result from the server. Instead, it will attempt to reuse as much of the existing DOM as possible.
```js
  import { hydrate } from "react-dom"
  import Profile from "./Profile"
  hydrate(<Profile />, document.getElementById("profile-container"));
```

Note:render() can still be used to render on top of server-side rendered markup, but it's recommended to use hydrate() now for that type of rendering in ReactJS 16.

Source: hackernoon.com

ReactJS 16 does not support error boundaries and portals in server-side rendering.

For more information, check out this excellent article on server-side rendering in ReactJS 16.

ReactJS 16 Deprecations and Breaking Changes

There a few deprecations and a number of breaking changes in ReactJS 16.

  • Discontinued support for React Add-ons.
  • Calling setState with null no longer triggers an update.
  • Calling setState directly inside the render() method always causes an update.
  • setState callbacks now fire immediately after componentDidMount or componentDidUpdate.
  • The componentDidUpdate lifecycle no longer accepts the prevContext parameter.
  • ReactDOM.render() and ReactDOM.unstable_renderIntoContainer() now return null if called from inside a lifecycle method.
  • Previously, changing the ref to a component would always detach the ref before that component's render was called. Now, we change the ref later, when applying the changes to the DOM.
  • As I mentioned earlier, hydrating a server-rendered container now has an explicit API. Use ReactDOM.hydrate instead of ReactDOM.render if you're reviving server rendered HTML. Keep using ReactDOM.render if you're just doing the client-side rendering.

For more information, check out the full list of deprecations and breaking changes on GitHub.

There has been a lot of performance observation and testing done by apps that have made the upgrade to ReactJS 16. And so far, there has been a lot of cheer and positive feedback for ReactJS 16. In fact, Twitter Lite already uses ReactJS 16.

The Twitter Lite engineering team discovered that the app's bundle size reduced a little and there were very clear improvements on large trees.

Conclusion

ReactJS is an awesome front-end library to employ in building your user interfaces. It is faster now because it runs on React Fiber and allows you to build more performant, smoothe UIs for your web and native applications.

ReactJS 16 came loaded with lots of new features and significant improvements. Kudos to the ReactJS team and the JavaScript open source community for all their efforts in making ReactJS a better tool.

Have you switched to ReactJS 16 yet? What are your thoughts? Let me know in the comments section! 

Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.

Topics:
web dev ,react ,reactjs 16 ,javascript libraries

Published at DZone with permission of Prosper Otemuyiwa, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}