React Memo
使用 memo
會導致 React 在元件的 props 未發生更改時跳過該元件的渲染。
這可以提高效能。
本節使用 React Hooks。有關 Hooks 的更多資訊,請參閱 React Hooks 部分。
問題
在此示例中,即使 todos 未更改,Todos
元件也會重新渲染。
示例
index.js
:
import { useState } from "react";
import ReactDOM from "react-dom/client";
import Todos from "./Todos";
const App = () => {
const [count, setCount] = useState(0);
const [todos, setTodos] = useState(["todo 1", "todo 2"]);
const increment = () => {
setCount((c) => c + 1);
};
return (
<>
<Todos todos={todos} />
<hr />
<div>
Count: {count}
<button onClick={increment}>+</button>
</div>
</>
);
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
Todos.js
:
const Todos = ({ todos }) => {
console.log("child render");
return (
<>
<h2>My Todos</h2>
{todos.map((todo, index) => {
return <p key={index}>{todo}</p>;
})}
</>
);
};
export default Todos;
單擊 increment 按鈕時,Todos
元件會重新渲染。
如果該元件很複雜,可能會導致效能問題。
解決方案
要解決此問題,我們可以使用 memo
。
使用 memo
來防止 Todos
元件不必要地重新渲染。
將 Todos
元件的匯出包裝在 memo
中
示例
index.js
:
import { useState } from "react";
import ReactDOM from "react-dom/client";
import Todos from "./Todos";
const App = () => {
const [count, setCount] = useState(0);
const [todos, setTodos] = useState(["todo 1", "todo 2"]);
const increment = () => {
setCount((c) => c + 1);
};
return (
<>
<Todos todos={todos} />
<hr />
<div>
Count: {count}
<button onClick={increment}>+</button>
</div>
</>
);
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
Todos.js
:
import { memo } from "react";
const Todos = ({ todos }) => {
console.log("child render");
return (
<>
<h2>My Todos</h2>
{todos.map((todo, index) => {
return <p key={index}>{todo}</p>;
})}
</>
);
};
export default memo(Todos);
現在,僅當傳遞給 Todos
元件的 props todos
更新時,Todos
元件才會重新渲染。