React 高階組件

  • 2022 年 8 月 16 日
  • 筆記

高階組件(HOC)

高階組件(Heigher Order Component)也被稱之為高階函數,容器組件,高階組件是類組件編程中的一種重要代碼邏輯復用技巧。

高階組件的語法

接收一個React組件作為入參,經過修飾,最後返回一個新的React組件,所以這個入參的React組件被稱之為「UI組件」;這個高階組件被稱之為「容器組件」。注意:在高階組件中無論怎麼對UI組件進行修改都不能修改。所以高階組件是一種純函數。

什麼是純函數

入參不能被修改,並且相同入參返回的是相同結果的函數,都叫做純函數。

 解決高階組件導致屬性丟失

封裝自定義高階組件時,如果props屬性丟失,可以使用屬性穿透(屬性繼承)解決

如何使用高階組件

  • 類組件可以使用Hoc(page)或者裝飾器語法@page
  • 函數組件只能使用Hoc(page)組件和 高階組件的區別

組件和 高階組件的區別

  • 組件是將props轉換為UI
  • 高階組件是將組件轉換另一個組件

高階組件的使用場景

  • 在路由中withRounter(),在轉檯管理中content(),在Mobx中有inject()或者observer()
  • 使用高階組件給頁碼添加公共的視圖結構,比如水印等。
  • 使用高階組件可以注入全局的公共方法,比如彈窗,校驗等。
  • 使用高階組件可以添加相同的業務功能,比如DOM功能,BON功能,訂閱功能等。
  • 使用高階組件可以實現權限設計。

 

    import { PureComponent } from "react";

    //高階組件權限設計
    function studay (WrappedComponent){
        // return class extends PureComponent{
        //     render(){
        //         return(
        //             <>
        //                 <nav>導航欄</nav>
        //                 <WrappedComponent {...this.props}></WrappedComponent>
        //                 <footer>底部導航欄</footer>
        //             </>
        //         )
        //     }   
        // }
        return props =>(
            <>
                <nav>導航欄</nav>
                <WrappedComponent {...props}/>
                <footer>底部導航欄</footer>
            </>
        )
    }

    //
    const page = (arr) =>{
        console.log('權限',arr);
        //狀態管理中的角色信息
        const roles = ['user']
        const flag = roles.some(ele=>arr.includes(ele))
        return WrappedComponent =>{
            return props =>(
                <>
                    {flag ? <WrappedComponent {...props}></WrappedComponent>: <h1>你的權限不足</h1>}
                </>
            )
        }
    }

    //封裝瀏覽器窗口標題
    const title = title =>{
        return  Men => class extends PureComponent{
            componentDidMount(){
                document.title = title || '沐沐5'
            }
            render(){
                return(
                <Men {...this.props}></Men>
                )
            }
        }
    }
    
    //只有在class上才能使用裝飾器語法
    @page(['admin',])
    @studay
    class A extends PureComponent{
        render(){
            console.log(this.props);
            return (
                <>
                    <h1>高階組件</h1>
                </>
            )
        }
    }

    export default A