React 16 error boundaries stop one component killing the page

Before 16, an exception during render left React in an inconsistent state and the usual advice was to let it crash. 16 unmounts the whole tree by default, which is worse in isolation and correct as a default — and gives a way to catch it.

class Boundary extends React.Component {
  state = { failed: false };

  static getDerivedStateFromError() { return { failed: true }; }

  componentDidCatch(error, info) {
    report(error, info.componentStack);
  }

  render() {
    return this.state.failed ?  : this.props.children;
  }
}

A boundary catches errors below it in the tree, not in itself, so the top-level one cannot catch its own render. It also does not catch errors in event handlers, in async code or during server rendering — all of which are ordinary try/catch territory. Wrapping each independent panel rather than the whole application is what turns a blank page into one broken panel.