React Memo
如果组件的 props
没有更改,使用 memo 将导致 React 跳过渲染组件,可以提高性能。
React.memo()
是一个高阶函数,它与 React.PureComponent 类似,但是一个函数组件而非一个类。
本节使用 React Hook 钩子。有关 Hook 的更多信息,请参见 React Hooks 部分。
问题
在本例中,即使 todos
没有更改,Todos
组件也会重新渲染。
实例:
index.js:
import { useState } from "react";
import ReactDOM from "react-dom";
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>
</>
);
};
ReactDOM.render(<App />, document.getElementById('root'));
Todos.js:
import { useState } from "react";
import ReactDOM from "react-dom";
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>
</>
);
};
ReactDOM.render(<App />, document.getElementById('root'));
单击 "increment" 按钮时,Todos
组件将重新渲染。如果此组件比较复杂,则可能会导致性能问题。
解决方法
要解决此问题,我们可以使用 memo
。
使用 memo
可防止 Todos
组件不必要地重新渲染。
将 Todos
组件导出装在 memo
中:
实例:
index.js:
import { useState } from "react";
import ReactDOM from "react-dom";
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>
</>
);
};
ReactDOM.render(<App />, document.getElementById('root'));
Todos.js:
import { useState } from "react";
import ReactDOM from "react-dom";
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>
</>
);
};
ReactDOM.render(<App />, document.getElementById('root'));
现在,TODO
组件仅在通过 Props 传递给它的 TODO
更新时重新渲染。