React.memo() 是你的朋友
React.memo()
是每个 React 开发者必备的工具之一。它使我们能够记忆 React 组件。与任何工具一样,在深入研究如何使用之前React.memo()
,我们先来了解一下问题所在。
为什么要进行记忆?
记忆化是一个通用概念,其基本含义是缓存某种计算的结果以供后续使用。它是一种在编程领域广泛使用的优化技术。
要记住的一点是,无论何时使用记忆法,都必须有一个标准来规定缓存的结果何时不再有效并且必须重新进行计算。
为了理解这解决的问题,请考虑以下 React 组件:
import { useState, Fragment } from "react";
function App() {
const [count, setCount] = useState(0);
function handleDecrement() {
setCount((oldCount) => --oldCount);
}
function handleIncrement() {
setCount((oldCount) => ++oldCount);
}
return (
<Fragment>
<p>Count is {count}</p>
<button onClick={handleDecrement}>-</button>
<button onClick={handleIncrement}>+</button>
</Fragment>
);
}
export default App;
一个简单的组件,可以保持计数的增加或减少。
现在让我们向 中添加另一个组件<App />
。为了简单起见,我们将创建一个组件,该组件根据传递给它的 prop 的<Message />
返回某种消息。msgId
function Message(props) {
let msg = "hello, world";
if (props.msgId === 1) {
msg = "hey there!";
} else if (props.msgId === 2) {
msg = "hola!";
}
return <p>{msg}</p>;
}
我们在这里尽量保持简单,但想象一下,这个<Message />
组件需要进行一些繁重的计算,或者可能需要向外部 API 发送请求才能获取最终消息。我们将通过添加大家喜欢的console.log()
组件来模拟这种情况。
function Message(props) {
let msg = "hello, world";
console.log("Just performed some seriously heavy computation");
if (props.msgId === 1) {
msg = "hey there!";
} else if (props.msgId === 2) {
msg = "hola!";
}
return <p>{msg}</p>;
}
让我们更新<App />
组件以使用<Message />
。
import { useState, Fragment } from "react";
function Message(props) {
let msg = "hello, world";
console.log("Just performed some seriously heavy computation");
if (props.msgId === 1) {
msg = "hey there!";
} else if (props.msgId === 2) {
msg = "hola!";
}
return <p>{msg}</p>;
}
function App() {
const [count, setCount] = useState(0);
function handleDecrement() {
setCount((oldCount) => --oldCount);
}
function handleIncrement() {
setCount((oldCount) => ++oldCount);
}
return (
<Fragment>
<Message msgId={1} />
<p>Count is {count}</p>
<button onClick={handleDecrement}>-</button>
<button onClick={handleIncrement}>+</button>
</Fragment>
);
}
export default App;
在下面的视频中,请特别注意每次count
改变时间时都会进行大量计算。
要了解为什么每次更改时都要进行大量计算
count
,请查看此文章:React 中的重新渲染
此时,退一步想想我们的 UI 此刻是多么低效。count
虽然没有<Message />
任何影响,但每次count
更新时,仍然需要进行大量计算。我们只希望在更改时进行计算,msgId
因为更改msgId
应该导致不同的消息。
React.memo() 来帮忙
React.memo()
是一个高阶组件。它接受一个组件作为参数,并记录其结果。只有当原始组件的 props 发生变化时,记录的结果才会更新。
要使用React.memo()
,只需将组件作为参数传递并保存结果即可。我们的<Message />
组件将变为:
import { useState, Fragment, memo } from "react";
const Message = memo(function (props) {
let msg = "hello, world";
console.log("Just performed some seriously heavy computation");
if (props.msgId === 1) {
msg = "hey there!";
} else if (props.msgId === 2) {
msg = "hola!";
}
return <p>{msg}</p>;
});
注意:我
memo()
这里只导入了。如果你已经React
导入了,你可以使用React.memo()
而不是memo()
。
现在我们的代码如下所示:
import { useState, Fragment, memo } from "react";
const Message = memo(function (props) {
let msg = "hello, world";
console.log("Just performed some seriously heavy computation");
if (props.msgId === 1) {
msg = "hey there!";
} else if (props.msgId === 2) {
msg = "hola!";
}
return <p>{msg}</p>;
});
function App() {
const [count, setCount] = useState(0);
function handleDecrement() {
setCount((oldCount) => --oldCount);
}
function handleIncrement() {
setCount((oldCount) => ++oldCount);
}
return (
<Fragment>
<Message msgId={1} />
<p>Count is {count}</p>
<button onClick={handleDecrement}>-</button>
<button onClick={handleIncrement}>+</button>
</Fragment>
);
}
export default App;
这次,请注意,当应用程序刷新时计算已经完成,但更改count
不再具有该结果。
👉🏻 订阅我的新闻通讯:点击此处
👉🏻 在 Twitter 上关注我:点击此处
文章来源:https://dev.to/therealnrf/reactmemo-is-your-friend-e6p