React is one of the most famous libraries to develop user interfaces which is known for its performance by implementing killer features like virtual DOM. Facebook officially released React 16 on Sep 26, 2017. The goal of this blog is to have a quick look at what’s changed in React 16 and the new exciting features.
Reference: Official announcement is here
React 16 has come with new features, complete re-write on internal algorithm and removal of deprecated addons from version 15. Though it is a complete rewrite, React team has done a great job by keeping the older version code compatible with new version code.
New JS Environment Requirements
The first and foremost point to peep into is the new dependencies that react library has, it now depends on ES6/ES2015 collection types Map and Set. All modern browsers understand ES6 collection types but if you need to have a support for older browsers, you need to add polyfill to support these collection types.
New return types supported for render method
In React 15, a render function of a class-based component or functional component can return only a valid react element or null. If you attempt to return any other you would see an error like below
A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.
Now in React 16 render method can return the following
String and numbers
Portals created using ReactDOM.createPortal
Array (called as Fragments)
Better error handling
There were many issues reported on the react github repo about cryptic errors or inconsistent behavior at runtime from react during rendering, when state was broken (throwing exceptions within event handlers would have unpredictable results) and application is recovered only from page refresh, now React 16 has an answer to such issues with resilient error-handling strategy.
Now in React 16, by default when an error is thrown inside a component’s render or lifecycle methods, the whole component tree is unmounted to ensure that the erratic application data is not shown, hence behaving consistently in case of unhandled exceptions. This may seem strange, but from an application standpoint it is always better to show the right data to the end user rather than an inconsistent state. For example, in a ticket booking application if there is any error during the booking process, it is better not to show false booking information. When I saw the blog post about Error handling in React 16 from Dan first, I was thinking why can't we have try/catch like mechanism in UI and the blog has answer, Error Boundaries.
As React is all about developing components, Error boundaries are nothing but components which implement new lifecycle method componentDidCatch (error, info). This lifecycle hooks give you an opportunity to take actions when an error is encountered, also this is the place where you can log your error information to your backend system.
Once the Error boundary component is created, you can use it to nest other components you wish to handle the errors like below.
Have you ever struggled with modals or loading bars in React mostly when it comes to styling?
Portals is an answer to this problem without compromising in the React way. With portals, you can render the React children into a DOM node that exists outside the DOM hierarchy of the parent component
Using the above method from ReactDOM library, you can mount React children in the desired container. First argument takes the react renderable children and the second parameter is the container in the DOM.
Look into this
Custom DOM Attributes
In past, React used to ignore attributes which are not whitelisted in React. If you have a JSX with any custom attribute, React would simply skip those. In React 16, support for custom attributes is added which means any attributes which are not known to React are also part of the final DOM. This has helped React in reducing the bundle size as in the past, React internally bookkeeps all the valid React DOM attributes and now with support for custom attribute, no more bookkeeping is needed as all attributes stand valid now.
Better Server Side Rendering
As on client-side rewrite, React 16 server side also got a complete rewrite which has brought most of the client features availability to server side with improved performance. It will be a redundant effort to write about SSR features of React. React Core team member Sasha Aickin wrote a great article describing React 16's SSR improvements.
New Core Architecture
Code named "Fiber" is a new core architecture of React.
"React Fiber is a complete, backwards compatible rewrite of the React core which enables sophisticated scheduling of rendering work" - Adam Wolff
Here is a great video by Lin Clark explaining about React fiber architecture during React conference 2017, it was an amazing overview with her cartoon style of introduction. The explanation given below is mostly derived from her talk.
Getting into the details of fiber would need an article itself, hence will keep explanation limited to import aspects of this architecture
At the core of React are 2 important things, first reconciliation and second render. Renders are pluggable as they change from platform to platform as React is not limited only to web today (for e.g., React Native has different render). Now coming to reconciliation - it is a process of finding the changes to DOM tree and React 15 uses diffing algorithm to do the same. Now in React 16, Fiber is the new reconciler.
React is well suited for rendering data but not for animating things, as for animations to be fluid 60 frames per second rendering must be achieved else we can notice the lag in animation. To solve this issue, the main feature in fiber is incremental rendering - which means rendering work can be split into chunks and spread out over multiple frames (sophisticated scheduling of rendering work)
Let’s understand how the reconciler and render work together. Once reconciler calculates the diff tree then it flushes to rendering environment, this is the cause to lag animations as the browser main thread (which is single threaded) would be stuck with rendering work causing lag in handling other priority works. When dealing with user interfaces, the problem is that if too much work is executed all at once, it can cause animations to drop frames and look choppy. Newer browsers (and React Native)[for older browsers react polyfill these APIs] implement APIs that help address this exact problem: requestIdleCallback schedules a low priority function to be called during an idle period, and requestAnimationFrame schedules a high priority function to be called on the next animation frame.
Typically, the program's execution is tracked using call stack. When a function is executed, a new stack frame is added to the stack. Processing thread can pick up next work only up on call stack is emptied which means execution cannot be paused once stack frames are generated onto stack. Now to get the incremental rendering work there should be a mechanism which virtualizes call stack to optimize for rendering UIs. This is the whole purpose of Fiber, which virtualizes the stack implementation by the keeping stack frames in memory and execute them when needed on priority. (this concept is similar to how async programming is managed with event loop, where blocking tasks are emptied out of stack and brought back later point of time into queue). That’s a very high-level understanding of Fiber. Will get back with detailed post soon about Fiber.
Before the release of React 16, there was a chaos in react community about React licensing. Now React 16 and some other Facebook opensource work is available under the MIT license. React team also licensed 15.6.2 under MIT, for those who are unable to upgrade immediately.