跳至主要内容

[react] 透過 React.memo 避免重新轉譯

資料來源:

在撰寫 React 時,當父層元件重新轉譯時,子層元件就會跟著重新轉譯,即使子層的資料並沒有任何變更。

舉例來說,父元件 <App>

// ./src/App.js
import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';
import Greeting from './Greeting';

import './styles.css';

function App() {
const [counter, setCounter] = useState(0);

useEffect(() => {
const intervalId = setInterval(() => setCounter(counter + 1), 3000);
return () => {
console.log('------ cleanUp ------');
clearInterval(intervalId);
};
}, [counter]);

console.log('App render');
return (
<div className="App">
<Greeting name="Aaron" />
</div>
);
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

子元件 <Greeting>

// ./src/Greeting
import React from 'react';

const Greeting = ({ name }) => {
console.log('Greeting component render');
return <h1>Hello, {name}</h1>;
});

export default Greeting;

在不做任何事的情況下,只要 <App> 重新轉譯,子元件 <Greeting> 就會跟著重新轉譯,即使 name 沒有任何改變:

React.memo

對於 <Greeting> 來說,會有很多次是沒有必要的重新轉譯,這時候就是適合使用 React.memo 的時機,React.memo 是一個 HOC,當我們把原本的 <Greeting> 元件透過 React.memo 包起來後,只要 props 沒有改變的情況下,<Greeting> 元件就不會重新轉譯:

// ./src/Greeting.js
import React from 'react';

const Greeting = React.memo(({ name }) => {
console.log('Greeting component render');
return <h1>Hello, {name}</h1>;
});

export default Greeting;

結果會像這樣:

React.memo

如此就可以減少多次不必要的轉譯。