在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));