Introduction to React (5) Error boundaries
In this blog we continue with our advanced guide to the React doc.
This time our main content is the wrong boundary.
What is wrong boundary?
In the past, JavaScript errors within components would cause the internal state of React to be corrupted, and on the next render 产生 可能无法追踪的 错误These errors are basically caused by earlier errors in other code (non-React component code), but React does not provide a way to handle these errors gracefully in components and cannot recover from errors.
JavaScript errors in some UIs should not cause the entire application to crash. To solve this problem, React 16 introduces a new concept - error boundaries.
An error boundary is a React component that can capture and print JavaScript errors that occur anywhere in its child component tree, and it renders an alternate UI instead of rendering the crashed child component tree. Error boundaries capture errors during rendering, in lifecycle methods, and in constructor functions throughout the component tree.
Attention
Error boundary ** cannot ** catch errors generated in the following scenarios:
If defined in a class component static getDerivedStateFromError()
Or componentDidCatch()
When either (or both) of these lifecycle methods, then it becomes an error boundary. When an error is thrown, use’static getDerivedStateFromError () 'to render the alternate UI and’component DidCatch () ’ to print the error message.
1 | class ErrorBoundary extends React.Component { |
Then you can use it as a regular component.
1 | <ErrorBoundary> |
The error boundary works similar to JavaScript’s catch {}, except that the error boundary is only for React components. Only class components can be error boundary components. In most cases, you only need to declare the error boundary component once and use it throughout the application.
Note that an error boundary can only catch the errors of its subcomponents, it cannot catch its own errors. If an error boundary fails to render an error message, the error bubbles up to the nearest upper error boundary, similar to how catch {} works in JavaScript.
Where should the wrong boundary be placed?
The granularity of the error boundary is up to you. You can wrap it in the topmost routing component and show the user an “Something went wrong” error message, just like server level frameworks often handle crashes. You can also wrap individual components in error boundaries to protect other parts of the application from crashing.
Uncaught error
As of React 16, any error not caught by the error boundary will cause the entire React component tree to be unloaded.
About
'Try ‘/’ catch 'is great but it can only be used for imperative code:
1 | try { |
However, React components are declarative and specify * what * needs to be rendered:
1 | <Button /> |
Error boundaries retain the declarative nature of React and behave as you would expect. For example, even if an error occurs in the’component DidUpdate ‘method and is caused by’setState’ in a deep component tree, it can still bubble up to the nearest error boundary.
About event handlers
Error boundaries ** cannot ** catch errors inside the event handler.
React doesn’t need error boundaries to catch errors in event handlers. Unlike render methods and lifecycle methods, event handlers don’t fire during rendering. So if they throw exceptions, React is still able to know what needs to be displayed on the screen.
If you need to catch an error inside an event handler, use a normal JavaScript’try ‘/’ catch 'statement:
1 | class MyComponent extends React.Component { |
Please note that the above example only demonstrates normal JavaScript behavior and does not use error boundaries.
Summary
First of all, the error boundary is also a component, but it is defined by the implementation
static getDerivedStateFromError()
OrcomponentDidCatch()
Either (or both) of these two lifecycle methods.This so-called error boundary acts like’try/catch ', the content in the middle of the error boundary can be compared to the content in try, and after catching the error, at the error boundary
static getDerivedStateFromError()
OrcomponentDidCatch()
The former is used to render the alternate UI, and the latter is used to print the log.Error boundary ** cannot ** catch errors generated in the following scenarios:
- Incident handling (了解更多)
- Asynchronous code (e.g. setTimeout or requestAnimationFrame callback functions)
- server-side rendering
- errors thrown by itself (not its child components)