React.memo
给了我们React中纯元件的能力,但对于基于功能的元件,而不是基于类的元件。
记忆化
是计算机科学术语,意思是缓存昂贵函数调用的结果,并在参数相同时返回缓存版本。
在反應方面:
我们不希望MyNewComponent
在通过的props
相同时重新渲染。
简单的例子对比
我已经创建了(以下Codesandbox
中的示例,以帮助在你的头脑中巩固React.memo
的工作方式)(https://codesandbox.io/s/kind-wilbur-2zl0g)。
这是一个简单的应用程序,计算按钮被点击的次数. 您可以从下面的屏幕截图中看到我们在页面顶部有一个标签。
假设Banner
是一个用户界面组件,可以有不同的类型,在这种情况下,您希望使用info
类型的标签,以便如下创建您的Banner
:
1<Banner type="info" />
我们的CounterComponent
看起来像这样:
1class CounterComponent extends Component {
2 state = { buttonPressedCount: 0 };
3 render() {
4 const { buttonPressedCount } = this.state;
5 return (
6 <div className="new-component">
7 <h4>Button Pressed Count: {buttonPressedCount}</h4>
8 <button
9 onClick={() =>
10 this.setState({ buttonPressedCount: buttonPressedCount + 1 })
11 }
12 >
13 Increase Count
14 </button>
15 <Banner type="info" />
16 </div>
17 );
18 }
19}
我们的Banner
组件看起来如下:
1const Banner = props => {
2 const { type } = props;
3
4 if (type === "info") {
5 return <div className="info-banner">I am an info banner</div>;
6 }
7};
在我们的CounterComponent
,每当我们点击按钮时,我们会增加按钮PressedCount
变量,这会导致重新渲染,这就是你所期望的。
为了绕过这一点,我们使用备忘录
,它作为PureComponent
的行为,因为它将停止重新渲染,当预告片
没有改变时。
1const Banner = memo(props => {
2 const { type } = props;
3
4 if (type === "info") {
5 return <div className="info-banner">I am an info banner</div>;
6 }
7});
现在我们的Banner
组件只会在其中的插件
更改时重新渲染。
这是React备忘录的核心基本理念。
平等
好吧,让我们更先进一点,谈论定制平等。默认情况下,备忘录
只对特许权和特许权的对象进行shallow
比较。
1React.memo(Component, [areEqual(prevProps, nextProps)]);
这与shouldComponentUpdate
类似,但在shouldComponentUpdate
中返回true
的逆转会导致另一个渲染,而areEqual
则是相反的。
假设我们有一个人
组件,它接受了一个亲
的人,这是一个对象,我们可以检查名字
是否相同。
1const areEqual = (prevProps, nextProps) => {
2 return (prevProps.name === nextProps.name)
3};
4React.memo(Person, areEqual);
结论
这是 React 的一个非常好的补充,允许我们使用功能组件,而无需担心不必要的重现。