React shipped a major version (v16.0) this week. Because the project is developed in the open, the community has been able to track the progress of this release, get a feel for what’s on the horizon, and even shape what lands in it. Naturally, we’ve been eagerly anticipating the overhaul of error handling.
Here we’ll summarise what’s new, dive into error handling and show you how to make the most of the new features by hooking them up to Bugsnag.
From the outside: in short, not a huge amount. However, the internals have had a complete rewrite – a project known as “Fiber”, which has been underway for over a year.
Because of this huge internal changeset, the maintainers focused largely on compatibility with existing apps – wisely enabling them to leverage the huge ecosystem of working React apps in the wild as a catalogue of real-life test cases. Luckily for you, some ahead-of-the-curve teams tried out the release candidates and helped to iron out the creases. 😉
As part of the rewrite many private/internal APIs have changed or been removed, so if you were monkeypatching or fiddling with anything you shouldn’t have, you will probably need to update that.
The main feature additions are:
render()return types: fragments, portals and strings
You can read all about the custom DOM attributes and
render() return types on
the React blog – they’re nice, but we’re much more interested
in error handling (surprised, much?).
Handling errors in React has been a frustrating endeavour. There’s been no consistent and failsafe way to catch and deal with errors, until now! The Fiber rewrite laid the groundwork for better error handling, starting with a new feature called Error Boundaries.
An error boundary is a React component with a
componentDidCatch(err, info) method.
Any errors occurring in a component tree get reported up to the nearest error boundary’s
componentDidCatch function, giving your app the chance to:
setState(…)to render an error/fallback state).
Additionally, unhandled errors (those not caught by an error boundary) will cause the entire tree to be unmounted. Quite a drastic measure indeed, but considering the alternative of attempting to continue with the app in some undefined state… that’s what got us into this mess in the first place!
The upshot is that you should use error boundaries in your app so that when something goes wrong, you provide your users with a sensible UI, and yourselves with a detailed report of what happened.
We’d find it hard to disagree with this advice from the React team when they introduced Error Boundaries to the world…
We … encourage you to use JS error reporting services … so that you can learn about unhandled exceptions as they happen in production, and fix them.
your tree gets unmounted you will already get notified. However, if you purposefully
catch errors with error boundaries, you can report them with more contextual information
which will help to you find and fix issues quicker. The bugsnag-react integration
<ErrorBoundary /> component, which you can use as follows:
// initialize bugsnag ASAP, before other imports import bugsnag from 'bugsnag-js' const bugsnagClient = bugsnag('API_KEY') import ReactDOM from 'react-dom' import React from 'react' import createPlugin from 'bugsnag-react' // wrap your entire app tree in the ErrorBoundary provided const ErrorBoundary = bugsnagClient.use(createPlugin(React)) ReactDOM.render( <ErrorBoundary> <YourApp /> </ErrorBoundary>, document.getElementById('app') )
Any component lifecycle errors within the
<ErrorBoundary /> will be caught and
handled by the
componentDidCatch() method. It’ll be reported to your dashboard
If you were wondering why we wrapped the
<YourApp/> component rather than having
the top-level component become an error boundary, note that an error boundary cannot
handle its own errors, only those occurring within its subtree.
To explore this in more detail, check out our example project.
So hopefully you’re as excited as we are about finally being able to handle errors gracefully in React. We wish you a smooth and speedy upgrade to v16.0 and hope to see you sending some high quality reports to your dashboard in the near future! 🎉
Editor’s Note: This post was updated on December 11, 2017, for accuracy and comprehensiveness.