幾週前 React 發佈了版本 16.6,一口氣推出了 lazymemocontextType 等新功能。而其中的 React.memo 就是過去 React.PureComponent 的 HOC 版本,比起過去改動成 PureComponent 要動到較大量的程式碼,如今只要套上 React.memo 即可。不過在 class component 可以寫 class method 自定 shouldComponentUpdate 的實作,function component 好像不能這樣搞?其實 memo 是有第二個參數可以使用的。

使用 PureComponent

以往要讓 Component 的 shouldComponentUpdate 自動進行 shallow equal 比對進行 re-render,只要把 class component 的 extends React.Component 部分改為 extends React.PureComponent 即可:

// before
class Demo extends React.Component {
// Something else...
render() {
return <div>{this.props.children}</div>;
}
}
// after
class Demo extends React.PureComponent {
// Something else...
render() {
return <div>{this.props.children}</div>;
}
}

你也可以自己寫 shouldComponentUpdate 來判斷 component 的 re-render 條件:

class Demo extends React.PureComponent {
shouldComponentUpdate(nextProps, nextState) {
// write something...
return true;
}
// Something else...
render() {
return <div>Demo</div>;
}
}

但假設 Component 是個 function component,那就必須改寫成單單只有 render function 的 class component,整體看起來會相當的不直觀:

// before
const Demo = ({ children }) => <div>{children}</div>;
// after
class Demo extends React.PureComponent {
render() {
return <div>{this.props.children}</div>;
}
}

使用 React.memo

但在 16.6 以後,只需要用 React.memo 並將 function component 作為參數即可:

// before
const Demo = ({ children }) => <div>{children}</div>;
// after
const Demo = React.memo(({ children }) => <div>{children}</div>);

可是如果想要自己實作 shouldComponentUpdate 的話好像就不知道怎麼寫了:

// ??? how to add shouldComponentUpdate?
const Demo = React.memo(({ children }) => <div>{children}</div>);

React.memo(Component, areEqual)

其實 React.memo 可以接受第二個參數,透過第二個參數的 function 來決定要不要 re-render。但是這邊要注意到的是:

詳細的說明可以到 官方文件 的 React.memo 章節 查閱。

const Demo = React.memo(
({ children }) => <div>{children}</div>,
(prevProps, nextProps) => {
/*
return true if passing nextProps to render would return
the same result as passing prevProps to render,
otherwise return false
*/
return false;
}
);

References

← Back to Home