博客 / 詳情

返回

react函數組件使用React.memo避免重複渲染

在react的類組件裏,我們可以通過shouldComponentUpdate來主動控制組件是否需要渲染,那麼在函數組件裏,有沒有類似的方法可以讓我們主動控制組件渲染呢?有的,那就是React.memo。

React官方文檔給出的介紹:

Class components can bail out from rendering when their input props are the same using PureComponent or shouldComponentUpdate. Now you can do the same with function components by wrapping them in React.memo.

類組件在使用了pureComponent或shouldComponent的時候會避免渲染。你現在可以通過使用React.memo包裹組件來實現同樣的效果。
const MyComponent = React.memo(function MyComponent(props) {
  /* only rerenders if props change */
});

基於此做了個函數封裝:MemoComponent

import React, { useState } from "react";
import isEqual from "react-fast-compare";

/**
 * 默認比較方法
 * 使用者可以自行實現compare方法
 * @param {*} prepProps 
 * @param {*} nextProps 
 * @returns 
 */
function defaultCompareFunc(prepProps, nextProps) {
    try {
        return isEqual(prepProps, nextProps);
    } catch (error) {
        console.warn("compare error", error);
    }
    return false;
}

function Container(props) {
    const { RenderItem, ...otherProps } = props;
    return <RenderItem {...otherProps} ></RenderItem>
}

/**
 * 
 * @param {*} component 要緩存的組件
 * @param {*} compare 緩存的方法,不傳則使用默認比較方法
 * @returns 
 */
function MemoComponent(component, compare = defaultCompareFunc) {
    const memoComponent = React.memo(component, compare);
    return (props) => {
        return <Container
            RenderItem={memoComponent}
            {...props} >
        </Container>
    }
}

export default MemoComponent;

一般使用方法

import React from "react"
import MemoComponent from "memoComponent"

function Component(props){
    return (
        <div>Hello World</div>
    )
}

const componentWithMemo = MemoComponent(Component);
export default componentWithMemo;

結合dva使用方法:

import React from "react"
import MemoComponent from "memoComponent"

function Component(props){
    return (
        <div>Hello World</div>
    )
}

export default connect(({ Component, loading }) => ({
    Component,
    loading: loading,
}))(MemoComponent(Component));
user avatar esunr 頭像 yilezhiming 頭像 iymxpc3k 頭像 yefengweiliang 頭像 mapvthree 頭像 wupengyu_55d86cdb45293 頭像 bd_68bd40c5df395 頭像 shen_5bbe318c912ed 頭像 liujunqi 頭像 notrynosuccess 頭像 jacheut 頭像 delai 頭像
15 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.