<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          深度學(xué)習(xí)React高階組件

          共 8292字,需瀏覽 17分鐘

           ·

          2020-09-05 14:25

          作者:忘言

          來源:SegmentFault 思否社區(qū)




          混合蛋白


          在了解高階組件之前我們先講一下mixin很多初級(jí)工程師對(duì)mixin的概念并不是很了解,首先解釋一下mixin


          mixin:在項(xiàng)目中有些一碼相同的代碼會(huì)重復(fù)使用,我們就可以進(jìn)行抽離,方便維護(hù),為了解決這個(gè)問題就是包裝成mixin方法,但是后來發(fā)現(xiàn)有mixin有很多缺點(diǎn)端,也許可以說高階組件就是mixin的衍生品,讓我們進(jìn)入今天的主題





          高階組件


          高階組件:本身是一個(gè)函數(shù),這個(gè)函數(shù)接受一個(gè)組件做為參數(shù),并且返回一個(gè)組件


          實(shí)現(xiàn)方式:屬性代理和反向繼承


          示例:


          function Hoc(WrappedComponent) {//hoc就是是個(gè)高階組件   接受一個(gè)組件做為參數(shù)    return class extends Component {//返回一個(gè)組件        render() {            return (                

          這是一個(gè)高階組件


          ) } }}


          那么高階組件有什么用?

          • 代碼規(guī)范
          • 抽離州
          • 操作道具
          • 獲取實(shí)例
          • 布局更改


          接下來我們一個(gè)個(gè)例子查看它的好處


          現(xiàn)在有一個(gè)組件ConfirmBox點(diǎn)擊按鈕后消失


          class Dialog extends Component {    constructor(props) {        super(props);        this.state = {            show:true,            msg:'這是一個(gè)對(duì)話框',            title:'對(duì)話框'        }    }    handleConfirm = () => {        this.setState({            show:!this.state.show        })    }    render() {        return (            

          {this.state.title}

          {this.state.msg}

          ) }}





          屬性代理


          現(xiàn)在我們使用高階組件把ConfirmBox組件里的state和回調(diào)函數(shù)抽離出來
          屬性代理可以做什么?


          • 抽離州
          • 操作道具
          • 獲取實(shí)例
          • 布局更改


          接下來對(duì)props進(jìn)行操作


          function Hoc(WrappedComponent) {//hoc就是是個(gè)高階組件   接受一個(gè)組件做為參數(shù)    return class extends Component {//返回一個(gè)組件        constructor(props) {            super(props);            this.state = {                show:true,                msg:'這是一個(gè)對(duì)話框',                title:'對(duì)話框'            }        }        handleConfirm = () => {            this.setState({                show:!this.state.show            })        }        render() {            return (                

          這是一個(gè)高階組件


          ) } }}class ConfirmBox extends Component { constructor(props) { super(props);
          }
          render() { return (

          {this.props.title}

          {this.props.msg}

          ) }}


          現(xiàn)在我們已經(jīng)把state和回調(diào)函數(shù)已經(jīng)抽離到高階組件中


          function Hoc(WrappedComponent) {//hoc就是是個(gè)高階組件   接受一個(gè)組件做為參數(shù)    return class extends Component {//返回一個(gè)組件        constructor(props) {            super(props);            this.state = {                show:true,                msg:'這是一個(gè)對(duì)話框',                title:'對(duì)話框'            }        }        handleConfirm = () => {            this.setState({                show:!this.state.show            })        }        render() {            const newProps = {                show:true,                msg:'這是新的props'            }            return (                

          這是一個(gè)高階組件


          ) } }}class ConfirmBox extends Component { constructor(props) { super(props);
          }
          render() { return (

          {this.props.title}

          {this.props.msg}

          ) }}


          到這里不知道會(huì)不會(huì)有人感覺這個(gè)和陣營(yíng)的UI和邏輯抽離很像,其實(shí)是沒錯(cuò)的,UI和業(yè)務(wù)邏輯拆分也類似,為什么那還要有高階組件呢


          這里需要強(qiáng)調(diào)地點(diǎn)一下高階組件的英文函數(shù)意味著參數(shù)是動(dòng)態(tài)的這一點(diǎn)很重要,如果有兩個(gè)組件有同樣的邏輯通過高階組件只需要改變實(shí)參就可以實(shí)現(xiàn)而UI和業(yè)務(wù)邏輯分解就不行。


          假設(shè):現(xiàn)在有一個(gè)ConfirmBox2和ComfirmBox1的邏輯一樣那我們直接改變參數(shù)就可以了


          Hoc(ConfirmBox2)


          簡(jiǎn)單一行我們就把邏輯推理給了ComfirmBox2

          使用高階組件相對(duì)比較靈活,這里我可能找的例子不好,請(qǐng)各位讀者見諒。

          通過ref訪問組件實(shí)例



                                  {...newProps} title={this.state.title}                        handleConfirm={this.handleConfirm}                        ref={ref => this.myInstance = ref}>

          這樣我們就得到了組件實(shí)習(xí)了





          反向繼承(不推薦使用)


          反向繼承:既然有繼承兩字肯定和extends脫不了干系,反向繼承就是通過繼承傳進(jìn)來的組件參數(shù)并且在render調(diào)用super.render實(shí)現(xiàn)的


          反向繼承:可以做什么?


          • 操作狀態(tài)
          • 渲染劫持


          最簡(jiǎn)單的例子:


          function Hoc(WrappedComponent) {//hoc就是是個(gè)高階組件   接受一個(gè)組件做為參數(shù)    return class extends WrappedComponent {//繼承傳進(jìn)來的組件        render() {            return (                super.render();//調(diào)用super.render
          ) } }}


          操作state:根據(jù)狀態(tài)的show判斷是否顯示組件


          function Hoc(WrappedComponent) {//hoc就是是個(gè)高階組件   接受一個(gè)組件做為參數(shù)    return class extends WrappedComponent {//返回一個(gè)組件        static displayName = `HOC(${WrappedComponent.displayName || WrappedComponent.name})`        componentWillMount() {            // 可以方便地得到state,做一些更深入的修改。            this.setState({                msg: '這是hoc修改的值'            });        }        render() {            return (                
          { super.render()}


          ) } }}


          渲染劫持

          function Hoc(WrappedComponent) {//hoc就是是個(gè)高階組件   接受一個(gè)組件做為參數(shù)    return class extends WrappedComponent {//返回一個(gè)組件        static displayName = `HOC(${WrappedComponent.displayName || WrappedComponent.name})`        componentWillMount() {            // 可以方便地得到state,做一些更深入的修改。            this.setState({                msg: '這是hoc修改的值'            });        }        render() {            if(this.state.show) {                return super.render()            }else {                return null            }        }    }}


          反向代理:為什么不推薦使用,因?yàn)椴僮鳡顟B(tài)容易覆蓋,并且生命周期函數(shù)也會(huì)覆蓋

          function Hoc(WrappedComponent) {//hoc就是是個(gè)高階組件   接受一個(gè)組件做為參數(shù)    return class extends WrappedComponent {//返回一個(gè)組件        static displayName = `HOC(${WrappedComponent.displayName || WrappedComponent.name})`        componentWillMount() {            // 可以方便地得到state,做一些更深入的修改。            this.setState({                msg: '這是hoc修改的值' //修改了msg的值            });        }        componentDidMount(){            console.log("hoccomponentDidMount")        }        render() {            if(this.state.show) {                return super.render()            }else {                return null            }        }    }}class ConfirmBox extends Component {    constructor(props) {        super(props);        this.state = {            show:true,            msg:'這是一個(gè)對(duì)話框',            title:'對(duì)話框'        }    }    handleConfirm = () => {        this.setState({            show:!this.state.show        })    }    componentDidMount() {        console.log("comfirmbox    componentDidMount")    }    render() {        return (            

          {this.state.title}

          {this.state.msg}

          ) }}


          從圖片可以修剪被包裹組件的componentDidMount生命周期函數(shù)組覆蓋了,如果要調(diào)用需要使用super.componentDidMount去調(diào)用,而且狀態(tài)也被覆蓋了另外,最重要的一點(diǎn)反向繼承不能保證子組件完全被渲染,這是什么意思?就是被包裹組件里的可能會(huì)丟失。





          高階組件使用場(chǎng)景


          頁面渲染


          function Hoc(WrappedComponent) {//hoc就是是個(gè)高階組件   接受一個(gè)組件做為參數(shù)    return class Test extends Component {//返回一個(gè)組件        static displayName = `HOC(${WrappedComponent.displayName || WrappedComponent.name})`        constructor(props) {            super(props);            this.state = {                show:true,                msg:'這是一個(gè)對(duì)話框',                title:'對(duì)話框'            }        }        handleConfirm = () => {            this.setState({                show:!this.state.show            })        }        componentDidMount() {            console.log(this.myInstance)        }
          render() { const newProps = { show:true, msg:'這是新的props' } if(this.state.show) { return {...newProps} title={this.state.title} handleConfirm={this.handleConfirm} ref={ref => this.myInstance = ref}> }else { return null }
          } }}


          邏輯復(fù)用:現(xiàn)在假設(shè)有兩個(gè)確認(rèn)框組件,他們的邏輯一樣,只有樣式不同,那我們就可以使用高階組件來實(shí)現(xiàn)


          import React,{Component} from 'react'
          import './Hoc.css'function Hoc(WrappedComponent) {//hoc就是是個(gè)高階組件 接受一個(gè)組件做為參數(shù) return class Test extends Component {//返回一個(gè)組件 static displayName = `HOC(${WrappedComponent.displayName || WrappedComponent.name})` constructor(props) { super(props); this.state = { show:true, msg:'這是一個(gè)對(duì)話框', title:'對(duì)話框' } } handleConfirm = () => { this.setState({ show:!this.state.show }) } componentDidMount() { console.log(this.myInstance) }
          render() { const newProps = { show:true, msg:'這是新的props' } if(this.state.show) { return {...newProps} title={this.state.title} handleConfirm={this.handleConfirm} ref={ref => this.myInstance = ref}> }else { return null }
          } }}class ConfirmBox extends Component { constructor(props) { super(props);
          }
          render() { return (

          {this.props.title}

          {this.props.msg}

          ) }}class ConfirmBox2 extends Component { constructor(props) { super(props);
          }
          render() { return (
          {this.props.title}

          {this.props.msg}

          ) }}
          export default { comfirmBox:Hoc(ConfirmBox), comfirmBox2:Hoc(ConfirmBox2)}

          109b7d945f9b0c65c485d99de7b9d7b8.webp

          369d5d91c177320715dbcd983555fbef.webp


          可以拋光組件只是樣式不同,邏輯相同我們就可以使用高階組件來實(shí)現(xiàn)邏輯替換




          點(diǎn)擊左下角閱讀原文,到?SegmentFault 思否社區(qū)?和文章作者展開更多互動(dòng)和交流。
          -?END -

          35ab2a0745da7559a79bdbfd07b02009.webp

          瀏覽 24
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲天堂中文8 | 操我综合| 亚洲精品一区二区三区在线观看 | 亚洲成人一区二区 | 逼中逼啪视频 |