頻道欄目
首頁 > 程序開發 > web前端 > HTML/CSS > 正文
React優化子組件render-個人文章-SegmentFault思否
2019-05-11 22:05:10           
收藏   我要投稿

在react中,父組件的重新render會引發子組件的重新render,但是一些情況下我們會覺得這樣做有些多余,比如:

父組件并未傳遞props給子組件 新傳遞的props渲染結果不變
class A extends React.Component {
    render() {
        console.log('render')
        return <p>這是A組件</p>
    }
}

class Main extends React.Component {
    render() {
        return (
            <p>
                // 點擊button會讓A不斷調用render
                <button onClick={() => this.setState({ a: 1 })}>Main</button>
                <A />
            </p>
        )
    }
}

為了解決這個問題,需要分為ES6類組件和函數式組件兩種:

類組件

使用shouldComponentUpdate來對props和state進行判斷以此決定是否進行render

class A extends React.Component {
    shouldComponentUpdate(nextProps, nextState) {
        //兩次props對比
        return nextProps.a === this.props.a ? false : true
    }
    render() {
        console.log('render')
        return <p>這是A組件</p>
    }
}

class Main extends React.Component {
    // ...
    render() {
        return (
            <p>
                <button onClick={() => this.setState({ a: 1 })}>Main</button>
                <A a={this.state.a} />
            </p>
        )
    }
}

通過返回false來跳過這次更新

使用React.PureComponent,它與React.Component區別在于它已經內置了shouldComponentUpdate來對props和state進行淺對比,并跳過更新

//PureComponent
class A extends React.PureComponent {
    render() {
        console.log('render')
        return <p>這是A組件</p>
    }
}

class Main extends React.Component {
    state = {
        a: 1
    }
    render() {
        return (
            <p>
                <button onClick={() => this.setState({ a: 1 })}>Main</button>
                <A a={this.state.a} />
            </p>
        )
    }
}

函數組件

使用高階組件React.memo來包裹函數式組件,它和類組件的PureComponent類似,也是對對props進行淺比較決定是否更新

const A = props => {
    console.log('render A')
    return <p>這是A組件</p>
}
// React.memo包裹A
const B = React.memo(A)

const Main = props => {
    const [a, setA] = useState(1)
    console.log('render Main')

    return (
        <p>
            // 通過setA(a + 1)讓父組件重新render
            <button onClick={() => setA(a + 1)}>Main</button>
            // 一直傳入相同的props不會讓子組件重新render
            <B a={1} />
        </p>
    )
}

它的第二個參數接受一個兩次props作為參數的函數,返回true則禁止子組件更新

其他

上面提到的淺比較就是根據內存地址判斷是否相同:

// extends React.Component
class A extends React.Component {
    render() {
        console.log('render A')
        console.log(this.props)
        return <p>這是組件A</p>
    }
}

class Main extends React.Component {
    test = [1, 2, 3]
    render() {
        console.log('render Main')
        return (
            <p>
                <button
                    onClick={() => {
                        // 父組件render
                        this.setState({})
                        this.test.push(4)
                    }}
                >
                    Main
                </button>
                <A test={this.test} />
            </p>
        )
    }
}

結果是:
使用React.component:
使用React.component
使用React.PureComponent:
使用React.PureComponent

使用React.component,點擊之后子組件重新render。改為React.PureComponent之后,點擊button子組件并不會render。也因此,PureComponent根據前后內存地址判斷是否相等,所以向子組件傳遞函數作為props時,使用內聯箭頭函數的形式將會導致子組件的重新render;所以可以用箭頭函數作為成員變量的形式再將函數引用作為props傳遞。

點擊復制鏈接 與好友分享!回本站首頁
相關TAG標簽
上一篇:【前端刷題筆記02】字節跳動2019面試題-一只想做全棧的貓-SegmentFault思否
下一篇:積夢前端的路由方案ruled-router-題葉-SegmentFault思否
相關文章
圖文推薦
點擊排行

關于我們 | 聯系我們 | 廣告服務 | 投資合作 | 版權申明 | 在線幫助 | 網站地圖 | 作品發布 | Vip技術培訓 | 舉報中心

版權所有: 紅黑聯盟--致力于做實用的IT技術學習網站

加拿大28火车判定方法