Hello, I’m Melio Piggy. React error boundary handling React error boundary handling React error boundary handling If not, then read my article, nanny level hand touch hand guidance!

case

Let’s first write an example, using CRA directly build a React project! Yarn start after all dependencies are installed

Perfect, so what’s the error boundary, what’s going to happen, very simple, let’s write anyScript, and then write the error code and see what happens, the code is like this

import React from 'react';
import logo from './logo.svg';
import './App.css';

const MakeError = () = > {
  const value: any = undefined; // This line is new, of type any, and assigned to undefined
  return (
    // We did undefined"
    <span>{value.notExist}</span>)}function App() {
  
  return (
    <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.tsx</code> and save to reload.
          </p>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React 
            <MakeError/>
          </a>
        </header>
    </div>
  );
}

export default App;
Copy the code

And then look at the page right now and see how it’s going to get angry

“Cannot read properties of undefined (reading ‘notExist’)” We made that mistake ourselves. (Funny face)

In the actual work, more or less there may be this error directly white screen, then how should we deal with it

Error boundary – React

The cause of the blank screen

The following quotes are from the official document error boundary, copied and pasted to explain the vernacular composition of this article hydrology (Happy face)

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

We had some debate about this decision, but in our experience, leaving a bad UI there is worse than removing it completely. For example, in a product like Messenger, presenting a user with an abnormal UI could cause the user to send the wrong message to someone else. Similarly, displaying the wrong amount is worse for a payment application than showing nothing at all.

This change means that when you migrate to React 16, you may find some crashes that already exist in your app but you didn’t notice. Adding error boundaries allows you to provide a better user experience when an exception occurs in your application.

Simply put, we didn’t handle the error. It didn’t feel happy to write the entire React component tree to show you the eye-roll because they thought leaving the wrong UI there was worse than eye-roll!

So where do we get to the critical part of dealing with error boundaries

False boundary concept

The following quotes are from the official document error boundary, copied and pasted to explain the vernacular composition of this article hydrology (Happy face)

JavaScript errors in part of the UI should not crash the entire app, and React 16 introduced a new concept called error boundaries to address this issue.

The error boundary is a React component that catches JavaScript errors that occur anywhere in the child component tree and prints those errors while displaying the degraded UI without rendering the child component tree that crashed. Error bounds catch errors during rendering, in lifecycle methods, and in constructors throughout the component tree.

Note that keywords are typo and display degraded UI at the same time

If either (or both) of the static getDerivedStateFromError() or componentDidCatch() lifecycle methods are defined in a class component, it becomes an error boundary. When an error is thrown, render the standby UI using static getDerivedStateFromError() and print the error message with componentDidCatch().

Note that only the class component can do this, and you need to define special lifecycle methods. The official documentation contains the code. Of course, I will not copy this completely, but I will write a simple error boundary component in conjunction with TS

<ErrorBoundary>
  <MyWidget />
</ErrorBoundary>
Copy the code

Show me the code. If there are no errors, I will display MyWidget. If there are errors, I will display degraded UI and print error messages. Let’s implement the simplest error boundary component to save the eyeless roll

Implementing error boundaries

The first step

New components folder, file error – a boundary. New benchmark, and then build a class component shelf (if installed vscode plug-in – ES7 React/story/GraphQL/React – Native snippets, Ps: RCC stands for React class Component.

Don’t ask me why I don’t write a function component, because it says in the documentation that error bounds have to be class components

The second step

With our ts, we know that our Component generic is class Component

, so the first item is our props, and the second item is our state

,>

We’re going to need to think about what we want to pass to props. We’re going to want to pass children if there is no error, and we’re going to want to pass degraded UI if there is an error, and we’re going to want to pass error to state

import { Component, ReactElement, PropsWithChildren } from 'react'

// If the UI component is degraded, props should pass an error, and return JSX
type FallbackRender = (props: { error: Error | null }) = > ReactElement

export default class ErrorBoundary extends Component<PropsWithChildren<{ fallbackRender: FallbackRender }>, { error: Error | null }> {
    state = {
        error: null.// The default value has no errors
    }
    render() {
        return (
            <div>

            </div>)}}Copy the code

The estimate that needs to be explained here is PropsWithChildren, and I wrote Utility Types hydrology before, and PropsWithChildren is really Utility Type, so let’s see how does that work

typePropsWithChildren<P> = P & { children? : ReactNode |undefined };
Copy the code

/ / assign (Object, props, and children); / / assign (Object, props, and children); / / Demote the UI when an error boundary is applied. Using this prop with children will be a bit pushy!

The third step

Implement static getDerivedStateFromError() by copying the official code below

import { Component, ReactElement, PropsWithChildren } from 'react'

// If the UI component is degraded, props should pass an error, and return JSX
type FallbackRender = (props: { error: Error | null }) = > ReactElement

export default class ErrorBoundary extends Component<PropsWithChildren<{ fallbackRender: FallbackRender }>, { error: Error | null }> {
    state = {
        error: null.// The default value has no errors
    }

    static getDerivedStateFromError(error: Error) {
        return { error };
    }

    render() {
        return (
            <div>

            </div>)}}Copy the code

The fourth step

It’s time for the final step in encapsulating this component, dealing with render’s logic

  • Render children normally without error
  • There is error rendering degraded UI

The final code is as follows

import { Component, ReactElement, PropsWithChildren } from 'react'

// If the UI component is degraded, props should pass an error, and return JSX
type FallbackRender = (props: { error: Error | null }) = > ReactElement

export default class ErrorBoundary extends Component<PropsWithChildren<{ fallbackRender: FallbackRender }>, { error: Error | null }> {
    state = {
        error: null.// The default value has no errors
    }

    static getDerivedStateFromError(error: Error) {
        return { error };
    }

    render() {
        const { error } = this.state
        const { children, fallbackRender } = this.props
        return error ? fallbackRender({ error }) : children
    }
}

Copy the code

Step 5

So let’s try out this new component, go to our app.tsx, and kick it off

import React from 'react';
import logo from './logo.svg';
import './App.css';
import ErrorBoundary from './components/error-boundary';

const ErrorInfo = ({ error }: { error: Error | null }) = > (
  <div>{error? .message}</div>
)

const MakeError = () = > {
  const value: any = undefined; // This line is new, of type any, and assigned to undefined
  return (
    // We did undefined"
    <span>{value.notExist}</span>)}function App() {

  return (
    <div className="App">
      <ErrorBoundary fallbackRender={ErrorInfo}>
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.tsx</code> and save to reload.
          </p>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
            <MakeError />
          </a>
        </header>
      </ErrorBoundary>
    </div>
  );
}

export default App;
Copy the code

Now take a look at the page to see if the descending UI is rendered

Beautiful! Very successful, this is much better than an eye-roll without any eyes, at least the user knows what’s wrong! Don’t worry, let’s see if we can render correctly with no errors. Let’s try and get rid of the MakeError component

import React from 'react';
import logo from './logo.svg';
import './App.css';
import ErrorBoundary from './components/error-boundary';

const ErrorInfo = ({ error }: { error: Error | null }) = > (
  <div>{error? .message}</div>
)

const MakeError = () = > {
  const value: any = undefined; // This line is new, of type any, and assigned to undefined
  return (
    // We did undefined"
    <span>{value.notExist}</span>)}function App() {

  return (
    <div className="App">
      <ErrorBoundary fallbackRender={ErrorInfo}>
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.tsx</code> and save to reload.
          </p>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >Learn React {/* MakeError to debug whether error boundaries work */} {/*<MakeError />* /}</a>
        </header>
      </ErrorBoundary>
    </div>
  );
}

export default App;
Copy the code

And we’re done, so we can just handle the error boundary

Third-party plug-ins

As mentioned earlier, this article is just a guide to implementing a basic and simple error boundary. How is it possible that such a basic function has not been made by a big man? Please see react-error-boundary! Here is a quick look at the source tips, any Github repository, as long as you link github.com in the middle of a 1s, such as github1s.com/bvaughn/rea… , you can view the source code directly in editor mode. The basic idea is almost the same as ours, so I won’t expand it here, and give you an opportunity to learn together!

conclusion

Today’s hydrological and finished, the summary is, read more documents, is not all of a sudden to learn new knowledge! Here is Melio pig, hope to help you!

reference

  • Error boundary – React
  • react-error-boundary