SoFunction
Updated on 2025-04-05

Implementation of Portals and Error Boundary Handling in React

Portals

It can be said to be a slot, but unlike slot in Vue, it refers to rendering a React element into a specified container (real DOM)

For example, the Modal component is generally rendered directly as a child element of the real structure of the body by default. Then we can create a React element with the help of (ReactElement, RealDOM container). Sample code:

import React from 'react'
import ReactDOM from 'react-dom'
import Modal from './components/Modal'

const PortalModal = (<Modal />, )

export default function App() {
    return <div className="app-container">
        <PortalModal />
    </div>
}

We can see in the browser console that the real Modal component is actually rendered as a direct child element of the body, but through the React developer tool, we can see that the Modal component is still in the App component in the structure of the virtual DOM tree, and the class name is app-container div

So, we can conclude that the virtual DOM tree structure of the React component can be inconsistent with the real DOM tree structure of the React component.

Therefore, you need to pay attention to the bubbling of events

  • Events in React are actually packaged
  • Its event bubbles are based on the structure of the virtual DOM tree, not the bubble mechanism of the real DOM tree.

Error boundary handling

By default, if an error occurs during rendering (render), the entire component tree will be uninstalled.
Error boundary: is a component that captures errors occurring in child components during rendering and has the ability to prevent errors from continuing to propagate to parent components.

Let a component catch an error (class component):

Use the static method static getDerivedStateFromError, this function will be triggered when the child component renders an error

  • Static method, so this cannot be used
  • This function returns a value (object) and overwrites the state with state
  • The triggering point is: After an error occurs in the rendering subcomponent, before updating the page
  • Only if an error occurs in the rendering of the child component will it be triggered (that is, if an error occurs in the own component or an error occurs in the brother component or parent component will not be triggered)
import React, {PureComponent} from 'react'

export default class ErrorBoundary extends PureComponent {
    state = {
        isError: false
    }
    static getDerivedStateFromError(error) {
        ('Rendering Error: ', error)
        return {
            isError: true
        }
    }
    render() {
        if () {
            return <span>Something Wrong...</span>
        }
        return 
    }
}

Use componentDidCatch(error, info) function

  • It's an example method
  • After an error occurs in rendering the subcomponent and the page is updated (changing the status will cause the component tree to be rebuilt after the component tree is uninstalled, which is a waste of efficiency)
  • Usually this function is used to pass and record error information to the background.
import React, {PureComponent} from 'react'

export default class ErrorBoundary extends PureComponent {
    state = {
        isError: false
    }
    componentDidCatch(error, info) {
        // info is the error summary information        ('Rendering Error: ', error)
        ('Rendering info: ', info)
        ({
            isError: true
        })
    }
    render() {
        if () {
            return &lt;span&gt;Something Wrong...&lt;/span&gt;
        }
        return 
    }
}

What happens if the error bounds are not used?

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

Experience tells us that removing completely is better than keeping the wrong UI. For example, in a product like Messenger, presenting an exception UI to the user may cause the user to missend the information to others.

Adding error boundaries can provide you with a better user experience when an exception occurs in an application. For example, Facebook Messenger wraps the sidebar, message panel, chat history, and message input boxes in separate error boundaries. If some of these UI components crash, the rest will still be able to interact.

Note

Some errors, error boundary components will not catch

Errors in its own components

Asynchronous error (such as error thrown in setTimeout)

import React, {PureComponent} from 'react'

// 
export default class ErrorBoundary extends PureComponent {
    state = {
        isError: false
    }
    /* This function will not run */
    static getDerivedStateFromError(error) {
        ('Rendering Error: ', error)
        return {
            isError: true
        }
    }
    render() {
        if () {
            return &lt;span&gt;Something Wrong...&lt;/span&gt;
        }
        return 
    }
}

// Comp componentexport default funtion Comp() {
    setTimeout(() =&gt; {
        throw new Error('setTimeout error')
    }, 1000)
    return &lt;div&gt;Comp&lt;/div&gt;
}

//  useexport default function App() {
    return &lt;&gt;
        &lt;ErrorBoundary&gt;
            &lt;Comp /&gt;
        &lt;/ErrorBoundary&gt;
    &lt;/&gt;
}

Error thrown in event

That is: Only synchronization errors during rendering subcomponents are handled

This is the article about Portals and Error Boundary Handling in React. For more related content on React Portals and Error Boundary Handling, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!