溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

React中Portals與錯(cuò)誤邊界處理怎么實(shí)現(xiàn)

發(fā)布時(shí)間:2022-04-19 16:46:45 來源:億速云 閱讀:126 作者:iii 欄目:移動(dòng)開發(fā)

這篇“React中Portals與錯(cuò)誤邊界處理怎么實(shí)現(xiàn)”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“React中Portals與錯(cuò)誤邊界處理怎么實(shí)現(xiàn)”文章吧。

Portals

可以說是 插槽,但 不同于 Vue 中的 slot,它指的是將一個(gè) React 元素渲染到指定的容器 (真實(shí) DOM) 中

比如說,Modal 組件一般默認(rèn)直接作為 body 的真實(shí)結(jié)構(gòu)的子元素渲染出來,那么我們就可以借助 ReactDOM.createPortal(ReactElement, RealDOM container) 創(chuàng)建一個(gè) React 元素,示例代碼:

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

const PortalModal = ReactDOM.createPortal(<Modal />, document.body)

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

我們可以在瀏覽器控制臺(tái)中看到,真實(shí)的 Modal 組件其實(shí)是作為 body 的直接子元素渲染出來的,但通過 React 開發(fā)者工具,我們可以看到 Modal 組件在虛擬 DOM 樹的結(jié)構(gòu)中依舊在 App 組件下,類名為 app-container 的 div 中

所以,我們可以得出結(jié)論:React 組件虛擬 DOM 樹結(jié)構(gòu)與真實(shí) DOM 樹結(jié)構(gòu)可以是不一致的

因而需要注意事件冒泡

  • React 中的事件其實(shí)是經(jīng)過包裝的

  • 它的事件冒泡是根據(jù)虛擬 DOM 樹的結(jié)構(gòu)來冒泡的,而不是真實(shí) DOM 樹的冒泡機(jī)制

錯(cuò)誤邊界處理

默認(rèn)情況下,若一個(gè)組件在渲染期間 (render) 發(fā)生錯(cuò)誤,那么就會(huì)導(dǎo)致整個(gè)組件樹全部被卸載
錯(cuò)誤邊界:就是一個(gè)組件,用于捕獲 渲染期間 子組件發(fā)生的錯(cuò)誤,并有能力阻止錯(cuò)誤繼續(xù)向父組件傳播

讓某個(gè)組件捕獲錯(cuò)誤 (類組件):

使用靜態(tài)方法 static getDerivedStateFromError,子組件渲染錯(cuò)誤時(shí)會(huì)觸發(fā)此函數(shù)

  • 靜態(tài)方法,所以不能使用 this

  • 此函數(shù)返回值 (對(duì)象) 會(huì)與 state 混合覆蓋狀態(tài)

  • 觸發(fā)時(shí)間點(diǎn)為:渲染子組件發(fā)生錯(cuò)誤后,在更新頁(yè)面之前

  • 只有子組件渲染發(fā)生錯(cuò)誤,才會(huì)觸發(fā) (即自身組件發(fā)生錯(cuò)誤或其兄弟組件、父組件發(fā)生錯(cuò)誤均不會(huì)觸發(fā))

import React, {PureComponent} from "react"

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

使用 componentDidCatch(error, info) 函數(shù)

  • 是個(gè)實(shí)例方法

  • 運(yùn)行時(shí)機(jī)在渲染子組件發(fā)生錯(cuò)誤后,且頁(yè)面更新之后 (更改狀態(tài)會(huì)導(dǎo)致組件樹卸載完之后又重新構(gòu)建組件樹,比較浪費(fèi)效率)

  • 通常該函數(shù)用于往后臺(tái)傳遞并記錄錯(cuò)誤信息

import React, {PureComponent} from "react"

export default class ErrorBoundary extends PureComponent {
    state = {
        isError: false
    }
    componentDidCatch(error, info) {
        // info 即為錯(cuò)誤的摘要信息
        console.log("Rendering Error: ", error)
        console.log("Rendering info: ", info)
        this.setState({
            isError: true
        })
    }
    render() {
        if (this.isError) {
            return <span>Something Wrong...</span>
        }
        return this.props.children
    }
}

如果沒有使用錯(cuò)誤邊界會(huì)怎樣?

自 React 16 起,任何未被錯(cuò)誤邊界捕獲的錯(cuò)誤將會(huì)導(dǎo)致整個(gè) React 組件樹被卸載。

經(jīng)驗(yàn)告訴我們,完全移除比保留錯(cuò)誤UI更好。例如,在類似 Messenger 的產(chǎn)品中,把異常的 UI 展示給用戶可能會(huì)導(dǎo)致用戶將信息錯(cuò)發(fā)給別人。

增加錯(cuò)誤邊界能夠讓你在應(yīng)用發(fā)生異常時(shí)提供更好的用戶體驗(yàn)。例如,F(xiàn)acebook Messenger 將側(cè)邊欄、信息面板、聊天記錄以及信息輸入框包裝在單獨(dú)的錯(cuò)誤邊界中。如果其中的某些 UI 組件崩潰,其余部分仍然能夠交互。

注意點(diǎn)

某些錯(cuò)誤,錯(cuò)誤邊界組件不會(huì)捕獲

自身組件的錯(cuò)誤

異步的錯(cuò)誤 (如 setTimeout 中拋出的錯(cuò)誤)

import React, {PureComponent} from "react"

// ErrorBoundary.jsx
export default class ErrorBoundary extends PureComponent {
    state = {
        isError: false
    }
    /* 此函數(shù)不會(huì)運(yùn)行 */
    static getDerivedStateFromError(error) {
        console.log("Rendering Error: ", error)
        return {
            isError: true
        }
    }
    render() {
        if (this.isError) {
            return <span>Something Wrong...</span>
        }
        return this.props.children
    }
}

// Comp.jsx Comp 組件
export default funtion Comp() {
    setTimeout(() => {
        throw new Error("setTimeout error")
    }, 1000)
    return <div>Comp</div>
}

// App.jsx 使用
export default function App() {
    return <>
        <ErrorBoundary>
            <Comp />
        </ErrorBoundary>
    </>
}

事件中拋出的錯(cuò)誤

即:僅處理渲染子組件期間的同步錯(cuò)誤

以上就是關(guān)于“React中Portals與錯(cuò)誤邊界處理怎么實(shí)現(xiàn)”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI