Previously, React would block the entire thread as it calculated the tree. This process for reconciliation is now named “stack reconciliation”. While React is known to be very fast, blocking the main thread could still cause some applications to not feel fluid. Version 16 aims to fix this problem by not requiring the render process to complete once it’s initiated. React computes part of the tree and then will pause rendering to check if the main thread has any paints or updates that need to be performed. Once the paints and updates have been completed, React begins rendering again. This process is accomplished by introducing a new data structure called a “fiber” that maps to a React instance and manages the work for the instance as well as know its relationship to other fibers. A fiber is just a JavaScript object. These images depict the old versus new rendering methods.

Stack reconciliation — updates must be completed entirely before returning to main thread (credit Lin Clark)

Fiber reconciliation — updates will be batched in chunks and React will manage the main thread (credit Lin Clark)

React 16 will also prioritize updates by importance. This allows high priority updates to jump to the front of the line and be processed first. An example of this would be something like a key input. This is high priority because the user needs that immediate feedback to feel fluid as opposed to a low priority update like an API response which can wait an extra 100–200 milliseconds.

React priorities (credit Lin Clark)

By breaking the UI updates into smaller units of work, a better overall user experience is achieved. Pausing reconciliation work to allow the main thread to execute other necessary tasks provides a smoother interface and better perceived performance.

Error Handling

Errors in React have been a little bit of mess to work with, but this is changing in version 16. Previously, errors inside components would corrupt React’s state and provide cryptic errors on subsequent renders.

lol wut?

React 16 includes error boundaries will not only provide much clearer error messaging, but also prevent the entire application from breaking. After being added to your app, error boundaries catch errors and gracefully display a fallback UI without the entire component tree crashing. The boundaries can catch errors during rendering, in lifecycle methods, and in constructors of the whole tree below them. Error boundaries are simply implemented through the new lifecycle method componentDidCatch(error, info) .

Here, any error that happens in <MyWidget/> or its children will be captured by the <ErrorBoundary> component. This functionality behaves like a catch {} block in JavaScript. If the error boundary receives an error state, you as a developer are able to define what is displayed in the UI. Note that the error boundary will only catch errors in the tree below it, but it will not recognize errors in itself.

Moving forward, you’ll see robust and actionable errors like this:

omg that’s nice (credit Facebook)

Return multiple elements from render

You can now return an array, but don’t forget your keys !

render() {

return [

<li key="A">First item</li>,

<li key="B">Second item</li>,

<li key="C">Third item</li>,

];

}

Portals

Render items into a new DOM node. For example, it could be great to have a general modal component you portal content in to.

render() {

// React does *not* create a new div. It renders the children into `domNode`.

// `domNode` is any valid DOM node, regardless of its location in the DOM.

return ReactDOM.createPortal(

this.props.children,

domNode,

);

}

Compatibility

Async Rendering

The focus of the initial 16.0 release is on compatibility for existing applications. Async rendering will not be an option initially, but in later 16.x releases, it will be included as an opt-in feature.

Browser Compatibility

React 16 is dependent on Map and Set . To ensure compatibility with all browsers, you must include a polyfill. Popular options are core-js or babel-polyfill.

In addition, it will also depend on requestAnimationFrame , including for tests. A simple shim for test purposes would be:

global.requestAnimationFrame = function(callback) {

setTimeout(callback);

};

Component Lifecycle

Since React prioritizes the rendering, you are no longer guaranteed componentWillUpdate and shouldComponentUpdate of different components will fire in a predictable order. The React team is working to provide an upgrade path for apps that would break from this behavior.

Usage

Currently React 16 is in beta, but it will be released soon. You can start using version 16 now by doing the following: