国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

React中Portals與錯誤邊界處理實(shí)現

發(fā)布時(shí)間:2021-08-17 12:16 來(lái)源: 閱讀:0 作者:suressk 欄目: JavaScript 歡迎投稿:712375056

目錄

Portals

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

比如說(shuō),Modal 組件一般默認直接作為 body 的真實(shí)結構的子元素渲染出來(lái),那么我們就可以借助 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>
}

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

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

因而需要注意事件冒泡

  • React 中的事件其實(shí)是經(jīng)過(guò)包裝的
  • 它的事件冒泡是根據虛擬 DOM 樹(shù)的結構來(lái)冒泡的,而不是真實(shí) DOM 樹(shù)的冒泡機制

錯誤邊界處理

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

讓某個(gè)組件捕獲錯誤 (類(lèi)組件):

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

  • 靜態(tài)方法,所以不能使用 this
  • 此函數返回值 (對象) 會(huì )與 state 混合覆蓋狀態(tài)
  • 觸發(fā)時(shí)間點(diǎn)為:渲染子組件發(fā)生錯誤后,在更新頁(yè)面之前
  • 只有子組件渲染發(fā)生錯誤,才會(huì )觸發(fā) (即自身組件發(fā)生錯誤或其兄弟組件、父組件發(fā)生錯誤均不會(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) 函數

  • 是個(gè)實(shí)例方法
  • 運行時(shí)機在渲染子組件發(fā)生錯誤后,且頁(yè)面更新之后 (更改狀態(tài)會(huì )導致組件樹(shù)卸載完之后又重新構建組件樹(shù),比較浪費效率)
  • 通常該函數用于往后臺傳遞并記錄錯誤信息
import React, {PureComponent} from 'react'

export default class ErrorBoundary extends PureComponent {
    state = {
        isError: false
    }
    componentDidCatch(error, info) {
        // info 即為錯誤的摘要信息
        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
    }
}

如果沒(méi)有使用錯誤邊界會(huì )怎樣?

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

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

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

注意點(diǎn)

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

自身組件的錯誤

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

import React, {PureComponent} from 'react'

// ErrorBoundary.jsx
export default class ErrorBoundary extends PureComponent {
    state = {
        isError: false
    }
    /* 此函數不會(huì )運行 */
    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>
    </>
}

事件中拋出的錯誤

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

到此這篇關(guān)于React中Portals與錯誤邊界處理實(shí)現的文章就介紹到這了,更多相關(guān)React Portals與錯誤邊界處理內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。

人人妻人人澡人人爽欧美一区| 国产精品原创巨作AV女教师| 免费婬色男女乱婬视频| 少妇高潮太爽了在线观看免费| 免费A级毛片无码视频| 久久久久97国产精华液好用吗|