Preface: take notes, refer to: the react documents, the article involves the example: sanhuamao1.coding.net/public/note…

Error boundary

The Error boundary is a React component that catches and prints JavaScript errors that occur anywhere in its child component tree and renders the alternate UI. Error bounds catch errors during rendering, in the life cycle, and in constructors throughout the component tree.

It cannot catch errors in the following scenarios:

  • Event Handling (learn more)
  • Asynchronous code (such as setTimeout or requestAnimationFrame callback)
  • Server side rendering
  • Errors thrown by itself (not by its children)

use

These are the two life cycle approaches. Whenever a class component uses either, it becomes an error bound component

  • ComponentDidCatch () : Typo error
  • Static getDerivedStateFromError() : Render the standby UI

A:componentDidCatch()

class ErrorBoundary extends React.Component {
    constructor(props) {
      super(props);
      this.state = { hasError: false };
    }
    componentDidCatch(error, errorInfo) {
      this.setState({
          error:error,
          errorInfo:errorInfo
      })
    }
    render() {
      if (this.state.errorInfo) {
        return <div>
            {this.state.error&&this.state.error.toString()}<br/> {this.state.errorInfo.componentStack}
        </div>
        
      }
      // Normally, the child element is returned, which is the element wrapped by the component
      return this.props.children; }}Copy the code

A test component that reports an error if a non-letter is entered:

class Example extends React.Component{
    constructor(props){
        super(props)
        this.state={value:""}
        this.handleChange=(e) = >{
            this.setState({value:e.target.value})
        }
    }
    render(){
        const value=this.state.value
        if(/^[a-zA-Z]+$/.test(value)||value==="") {return  <input type="text" onChange={this.handleChange} placeholder="Letters only."/>
        }
        throw new Error('Wrong! '); }}Copy the code

App.js

<ErrorBoundary>
   <Example />
</ErrorBoundary>
Copy the code

Method 2:static getDerivedStateFromError()

class ErrorBoundary extends React.Component {
    constructor(props) {
      super(props);
      this.state = { hasError: false };
    }
    static getDerivedStateFromError(error) {
      return { hasError: true };
    }
    
    render() {
      if (this.state.hasError) {
        // Display degraded UI
        return <div>Wrong bro!</div>
      }
      return this.props.children; }}Copy the code


You can also use both.

ComponentDidCatch () doesn’t seem to be useful, because browsers typically tell you to view the error log only on the console, and the console prints the same error message without using the error bound component. In contrast, static getDerivedStateFromError(), which renders the spare component, is a bit more practical. Either way, it serves the purpose of creating an error bound component.

The error bound component works like JavaScript’s Catch {}, except that it only works with the React component. And only class components can be error bound components. Note that it cannot catch its own errors.

What if no error bounds were used?

Since React 16, any error not caught by the error boundary will cause the entire React component tree to be uninstalled.

Experience has taught us that it is better to remove the wrong UI completely than to keep it. For example, in a product like Messenger, displaying an abnormal UI to the user might cause the user to send the wrong message to someone else.

** Adding error boundaries allows you to provide a better user experience when an exception occurs in your application. ** For example, Facebook Messenger wraps the sidebar, message panel, chat history, and message entry fields in separate error boundaries. If some of the UI components crash, the rest can still interact.

Try/catch defects

Try/catch is great, but it can only be used for imperative code:

try {
  showButton();
} catch (error) {
  // ...
}
Copy the code

However, the React component is declarative and specifies what needs to be rendered:

<Button />
Copy the code

Why can’t you catch an internal error in the event handler?

React does not require error boundaries to catch errors in event handlers. Unlike the Render and lifecycle methods, event handlers do not fire during rendering. So React still knows what needs to be displayed on the screen if they throw an exception. If you need to catch errors inside event handlers, use plain JavaScript try/catch statements:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { error: null };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    try {
      // Perform the operation and throw if there is an error
    } catch (error) {
      this.setState({ error }); }}render() {
    if (this.state.error) {
      return <h1>An error was caught</h1>
    }
    return <button onClick={this.handleClick}>Click on the</button>}}Copy the code