Is Fiber ready yet? Yes, it is. Getting a little late to the react scene, I found it weird that people anticipated a feature so enthusiastically. I kept asking why people are not happy enough about the state of React at 15. Why not embrace 16 when it comes without so much anticipation? But people wanted it like Yesterday before it even arrived. Little did I know that React 16 is indeed a pack of awesomeness worth the anticipation and it is a complete backward-compatible rewrite of the React library.

Let us start with the very first thing you want to hear about, Fiber.

According to a talk by Lin Clark, Fiber improves perceived performance and responsiveness of a React application. And as we have learned from Eli Fitch in another talk, perceived performance is the only kind that matters.

Parallel processing has been known to be a way to speed up computing. When we are able to run multiple executions in parallel while sharing data, we refer to them as threads; without data sharing, they are just multiple processes. What makes for any proper multithreaded system is the scheduling of data interchange and the occurrence thereof splitting a big task into chunks and having the various threads handle it while retaining context. According to Wikipedia:

Fibers are an even lighter unit of scheduling which are cooperatively scheduled: a running fiber must explicitly "yield" to allow another fiber to run, which makes their implementation much easier than kernel or user threads. A fiber can be scheduled to run in any thread in the same process.

From Lin's talk, this image describes fiber's ability to have the main thread come back up periodically to see if there are any more tasks to be done.

Fiber provides scheduled checks for the main thread

And this is where the name React Fiber was derived from. React 16 introduces schedulers and watchers which aid with its asynchronous rendering. This basically means: Don't wait for a pile of DOM updates to happen in the virtual DOM before updating the DOM, just constantly check to find chunks that can be updated and do so. But it also goes beyond that by setting priorities to executions. By observing the kind of updates coming into the DOM, React places a priority that determines how that chunk of an update will be scheduled for entry into the DOM.

It does this with the aid of window.requestIdleCallback which is a browser feature for queuing functions that will get called during idle states of the browser. This helps with the scheduling process of React and gets polyfilled for browsers without support for the feature.

Besides fiber, there are more interesting features that React 16 introduced and some pre-existing features it shone a light upon by improving their mode of operation.

Functional SetState

This is NOT a new React 16 feature. It has been a feature of React since forever but was hardly known and therefore rarely used by anyone. Examples are shown in a recent post by Kelvin De Moya.

It was okay to use objects to update state in earlier versions of React, and we could do the same with Fiber, but by using functions instead we would be complementing the efficiency of fiber for our state updates:

// Object update - Not Recommended
this.setState({
  ...
})

// Functional update - Recommended
this.setState((state, props) => {
  return {...}
})

This is due to the new asynchronous rendering. Incrementing a property in setState may lead to unexpected results when handled as an object update. The functional update, on the other hand, provides the state as a callback when an update has been applied to it, giving a much safer and precise way to manage state.

Fragments

In preceding React versions, every parallel set of components had to be wrapped in a tag before rendering but React 16 allows fragment components to be rendered in parallel. To do this, it returns an array instead.

The following will be invalid in React 15

render(
  <header>My header</header>
  <main>My main content</main>
  <footer>My footer</footer>
, root)

to get it to work we have to wrap it in a div and that div will get rendered to the DOM, as well as:

<div>
  <header>My header</header>
  <main>My main content</main>
  <footer>My footer</footer>
</div>

Each of the components will resolve into their full DOM breakdown, and perhaps each of them have a div wrapper. It soon results in a gazillion of DOM nodes.

We could overlook the performance cost of redundant element wrappers in the DOM but as we have learned from Grace Hopper, every little optimization matters

Please cut off a nanosecond and send it over to me.

– Grace Hopper

This is why it is great that we can gain back some performance with this in React 16. Since we now get to return an array, the same rule of using keys for better a diffing algorithm applies. The fragmented render for React 16 will now take this form:

render([
  <header key="header">My header</header>,
  <main key="main">My main content</main>,
  <footer key="footer">My footer</footer>
], root)

which would render those elements/components in parallel and without an extra container. Note the inclusion of key directives to each of those elements.

Performance aside, this could become really handy for components that make up tables or flexbox layouts, as an extra layer of div might break the layout. It is however not recommended to use this unless there is an absolute need to.

The same level of flexibility we get by being able to render multiple elements without a wrapper also allows for rendering DOM nodes as strings rather than having to create a DOM element like a span tag for every tiny component we have to make. The following can now be done:

render('Hello there')

alternatively, as a stateless functional component:

export default const Foo = ({name}) => `Nice to meet you, ${name}`

Custom DOM Attributes

Unknown DOM attributes that are not props would get ignored pre-React 16, but now more DOM and SVG attributes could be used besides data attributes. You could have an element with attributes like this:

<div modal="#myModal" />

This opens room for one of the things that Vue has had as an edge over React — the ability to break SVG into components as briefly mentioned in the vue data visualization article and also better compatibility with third-party libraries with HTML API like the ones at MarkApp.

Error Boundaries

Error boundaries introduce a new lifecycle method that makes it easier to catch errors that occurred in a component and reply with a useful feedback rather than silently breaking or giving long and cryptic errors. This method is componentDidCatch, and it can be used as shown:

componentDidCatch(error, info){
  this.setState((state, props) => {
    return {
      hasError: true,
      errorInfo: info
    }
  })
}

then the UI can be updated to a helpful visual feedback through the state change. Here is a good example by Dan Abramov.

Portals

Before React 16, imperative APIs had to be used to achieve rendering children components outside of their main parent component to a separate one. It is like teleporting outside of Earth and unto Mars. Ain't that cool? You see something similar with the layout of templating engines but let us look at how React handles this within a component's render method declaratively:

render(){
  return ReactDOM.createPortal(
    this.props.children,
    document.getElementById('mars')
  )
}

given that we have our app HTML as

<body>
  <div id="earth"><!-- Everyone lives here --></div>
  <div id="mars"><!-- Only the chosen one can teleport here --></div>
</body>

For an applicable example, check here

Summary

The stack was the predecessor data structure for the reconciliation algorithm, and it updated the DOM each time there was a new update whereas Fiber keeps a record of the things to update in the form of a linked list which it then gradually updates in chunks based on priority rather than in large piles.

React 16 is also smaller in file size than previous versions of React and also uses the MIT license as introduced from 15.6.2 which means there's no need to be concerned about possible future legal problems that may come from using React for your projects.

Having told you all this, there are still more possibilities yet to be discovered in React 16.

Time to give it a spin!!!