Try React Fiber with Rekit

Nate Wang
6 min readJul 27, 2017

--

Facebook just announced React (Fiber) 16 beta, a new version of React, developed for almost 3 years. Though it’s a total rewrite, it is expected to be totally compatible with the previous React 15. Besides that, React fiber brings new features you must have been interested at for long time.

The best way to learn the new features is to use them in a real app. But creating a React app from scratch is not easy, luckily we can use Rekit to quickly create apps and try React Fiber. This article will just introduce how I try React Fiber. You can follow the article to try it by yourself, or just read though to see what React Fiber brings to us.

Why Rekit ? For below reasons:

  1. Rekit creates React app boilerplate with Redux, React router and webpack. You can test React Fiber features with these popular ecosystem projects.
  2. Rekit creates apps with samples (counter and Reddit API usage). So you can easily test React Fiber by simply modify sample code.
  3. You can create two same apps in seconds so that you can easily compare the difference between React 15 and 16(fiber).
  4. Rekit creates apps using React 15.6 by default, they can be upgraded to React 16 smoothly, even not throw a warning.

Never heard Rekit? Here is an overview introduction:

Ok, let’s start!

Create two apps using Rekit

First install Rekit if you have not:

> npm install -g rekit

Then create two apps in your workspace:

> rekit create app-15
> rekit create app-16

Now you have two apps created, then install dependencies for each:

app-15> yarn
app-16> yarn

To avoid port conflict, change the config in app-16/package.json:


“devPort”: 6085,
“portalPort”: 6086,
“buildPort”: 6087,

So the app-15 runs at 6075 and app-16 runs at 6085. Now let’s do our experiment!

1. Check backwards compatibility

This the first thing we care about. Is it really safe to upgrade to React Fiber for my app? Now let’s upgrade app-16 to React Fiber:

app-16> yarn add react@next react-dom@next

To verify it works correctly, we just need to start two apps to see if they behave exactly the same.

app-15> yarn start
app-16> yarn start

Now access http://localhost:6075 and http://localhost:6085 . Try navigating pages, counter and Reddit list samples in the home page. You can see they both work well and no warnings or errors in the dev tools console.

Rekit app upgraded to Fiber

Yes! You even can’t feel that React behind has upgraded to Fiber. It’s so easy, really impressive. By doing this, we have verified the backward compatibility, at least for a Rekit app.

2. Returning arrays from render

This is a much requested feature. Now we finally could return an array of elements from render method, no longer need to always wrap them in a container element.

To try it, let’s modify the Reddit list sample of the Rekit app. (Though it’s maybe not a typical case, we just want to check how it works.) Open ‘app-16/src/features/home/RedditList.js’ in your text editor, change ‘render’ method: remove the container ‘ul’ element:

render() {
return this.props.list.length > 0 ?
this.props.list.map(item => <li key={item.data.id}><a href={item.data.url}>{item.data.title}</a></li>)
: <li className="no-items-tip">No items yet.</li>
;
}

Now RedditList component renders an array! Then open ‘app-16/src/features/home/DefaultPage.js’, where the RedditList component is used, wrap the RedditList component with the ‘ul’ element:

<ul className="home-reddit-list">
<RedditList list={redditReactjsList} />
</ul>

Now we have left up the ‘ul’ element and RedditList component just returns an array of ‘li’ elements. Check the sample:

Yes, it works! We returned an array of elements in the render method and it works well. This is really a great feature brought by React 16.

3. Error handling and a new lifecycle method ‘componentDidCatch’

The new error handling mechanism is a breaking change. There are 3 points to be highlighted:

  1. More readable component stack traces for every error.
  2. The whole component tree will be unmounted when there’s any exception.
  3. Error boundaries mechanism

To try the new error handling mechanism, let’s make some error in our code, still in ‘src/features/home/RedditList.js’. Assume we use the incorrect data structure of the action data(this is a very common mistake in our daily coding):

  render() {
return this.props.list.length > 0 ?
this.props.list.map(item => <li key={item.item.data.id}><a href={item.data.url}>{item.data.title}</a></li>)
: <li className="no-items-tip">No items yet.</li>
;
}

We added a duplicated ‘item’ property, then there should be an error like ‘cannot read property of undefined’. Now we click ‘fetch reddit list’ button in the welcome page, compared to ‘app-15’, there are two differences:

  1. New error stack trace:
New error stack trace

There’s no such information in React 15, but exists in React 16 version. Really helpful for debugging.

2. The whole page becomes blank:

Whenever there’s javascript error, the whole component tree is removed

This is a big breaking change, whenever there’s any JavaScript error, the whole component tree will be unmounted. So even a very small component has error, the whole page is broken:

This behavior introduces the new error boundary mechanism, I will not introduce more about it since the official introduction is clear enough. But one point to highlight:

Note that error boundaries only catch errors in the components below them in the tree. An error boundary can’t catch an error within itself. If an error boundary fails trying to render the error message, the error will propagate to the closest error boundary above it.

That is we can’t handle render error in the component itself but in the parent components. Let’s add the error boundary for the error we just made, in the component ‘src/features/home/DefaultPage.js’ where RedditList is used.

The code is just the same as which in the official tutorial:

...
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>;
}
...
}
...

Then we back to the Rekit welcome page, it becomes:

We can see the error has been gracefully handled as expected without damaging the whole page.

Summary

So these are almost all new things we can feel from our daily development brought with React 16. We created React apps with Rekit, though the steps in the article are very simple. You could try anything you want by creating your own Rekit app.

I have to say it’s really impressive about the backwards compatibility. And as the release notes mentioned:

This initial React 16.0 release is mostly focused on compatibility with existing apps. It does not enable asynchronous rendering yet.

So we can’t experiment that big bang feature, let’s just wait for the next release.

Edit (28 July, 2017)

Thanks Richard Murnane’s reminding, npm test fails for React Fiber. The reason is the testing framework enzyme has not supported Fiber, let’s wait for the fix, I’ve seen they’ve been working hard on it: https://github.com/airbnb/enzyme/pull/1007

--

--