掌握React.Memo
React.memo
为我们提供了 React 中纯组件的能力,但针对的是基于函数的组件,而不是基于类的组件。
memoization
是计算机科学术语,意思是缓存昂贵的函数调用的结果,并在参数相同时返回缓存的版本。
在反应方面:
当传递的 props
相同时,我们不希望 MyNewComponent
重新渲染。
简单的计数器示例
我在 Codesandbox 中创建了 以下示例,以帮助您巩固 React.memo 的工作原理 。
这是一个简单的应用程序,可以计算按钮被点击的次数。 您可以从下面的屏幕截图中看到我们在页面顶部有一个横幅。
想象一下 Banner
是一个可以有不同类型的 UI 组件,在这种情况下,您想使用 info
类型的横幅,因此您可以按如下方式创建 Banner
:
<Banner type="info" />
我们的 CounterComponent
看起来像这样:
class CounterComponent extends Component { state = { buttonPressedCount: 0 }; render() { const { buttonPressedCount } = this.state; return ( <div className="new-component"> <h4>Button Pressed Count: {buttonPressedCount}</h4> <button onClick={() => this.setState({ buttonPressedCount: buttonPressedCount + 1 }) } > Increase Count </button> <Banner type="info" /> </div> ); } }
我们的 Banner
组件如下所示:
const Banner = props => { const { type } = props; if (type === "info") { return <div className="info-banner">I am an info banner</div>; } };
在我们的 CounterComponent
中,每次单击按钮时,我们都会增加 buttonPressedCount
变量,这会导致重新渲染,这是您所期望的。 这样做的问题是 Banner
组件也会重新渲染,即使传递给它的 props
没有改变。
为了避免这种情况,我们使用 memo
,它的作用类似于 PureComponent
,因为当 props
没有改变时它会停止重新渲染。 我们更新的代码如下所示:
const Banner = memo(props => { const { type } = props; if (type === "info") { return <div className="info-banner">I am an info banner</div>; } });
现在我们的 Banner
组件只会在 props
改变时重新渲染。
这是 React 备忘录的核心基本思想。
相等
好的,让我们更深入一点,谈谈自定义平等。 默认情况下,memo
仅对道具和道具的对象进行 shallow
比较。 您可以传递第二个参数来指示自定义相等检查:
React.memo(Component, [areEqual(prevProps, nextProps)]);
这类似于 shouldComponentUpdate
但相反,即 在 shouldComponentUpdate
中返回 true
会导致另一个渲染,而 areEqual
则相反。
想象一下,我们有一个 Person
组件接受了一个 prop
人,它是一个对象,我们可以检查 name
是否相同。
const areEqual = (prevProps, nextProps) => { return (prevProps.name === nextProps.name) }; React.memo(Person, areEqual);
结论
这是对 React 的一个非常好的补充,允许我们使用函数式组件而不必担心不必要的重新渲染。 一如既往,我希望你从这篇文章中学到了一些东西!