我最近决定刷新 react 的文档并遇到了https://reactjs.org/docs/react-api.html#reactmemo (React.memo)。
乍一看,它似乎是我几乎所有功能组件的不错选择。所以我就是这样做的,并应用于memo
所有这些。
我不确定我是否能够注意到显着的性能提升,但它肯定不会使速度变慢。
因此,问题是:我是否应该默认将 memo 应用于我的所有功能组件,以防万一,以便我可以捕获重新渲染很多元素的边缘情况?这有什么缺点/我需要注意的其他事情吗?
我最近决定刷新 react 的文档并遇到了https://reactjs.org/docs/react-api.html#reactmemo (React.memo)。
乍一看,它似乎是我几乎所有功能组件的不错选择。所以我就是这样做的,并应用于memo
所有这些。
我不确定我是否能够注意到显着的性能提升,但它肯定不会使速度变慢。
因此,问题是:我是否应该默认将 memo 应用于我的所有功能组件,以防万一,以便我可以捕获重新渲染很多元素的边缘情况?这有什么缺点/我需要注意的其他事情吗?
不,默认情况下您不应该记住所有功能组件。您应该根据具体情况决定何时执行此操作。
从文档:
如果你的函数组件在给定相同的 props 的情况下呈现相同的结果,你可以将它包装在对 React.memo 的调用中,以便在某些情况下通过记忆结果来提高性能。
想象一下,您向函数组件添加了一些副作用,例如,从Date.now()
. 该组件将在第一次使用某些props调用时按预期工作,但下次使用相同的props调用时,将使用旧时间。这可能会导致令人困惑的错误。
例如,如果一个组件不太可能使用相同的 props 被调用,那么记住结果可能会导致更糟糕的性能。毕竟,记忆只是存储对对象的函数调用的结果,其中键是从函数的输入中派生出来的,值是函数调用的结果。如果您永远不会使用它,为什么要存储它?
如果您的功能组件不需要很多 CPU 周期来渲染,那么任何性能优化都可能可以忽略不计。但是现在可以稍后向该组件添加副作用,忘记它正在被记忆,并浪费时间修复由此产生的错误。
再次,来自文档:
此方法仅作为性能优化存在。不要依赖它来“阻止”渲染,因为这会导致错误。
更简短的解释:
如果React.memo()
一切都让 React 更加高效和优化,那么它应该被视为默认行为,而不仅仅是一个选项(如纯函数)。
基本上,React.memo()
通过比较组件的先前和当前 props 来防止冗余重新渲染。
<Parent>
<Child />
</Parent>
通常,当重新Parent
渲染时,Child
默认情况下也会重新渲染。
与React.memo()
,如果重新渲染Child
时传入的 props没有改变Parent
,Child
则不重新渲染。
这里的问题是:为什么 React 知道传递给的 propsChild
在当前重新渲染中没有改变?
答案是:React 本身要做比较,而且是成本React.memo()
如果比较的时间 > 重新渲染整个Child
组件的时间,它甚至会减慢您的应用程序的速度。
不,这不是一个好主意,因为 React 对于大多数用例来说都非常快。如果我们的应用程序足够快并且我们没有任何性能问题,那么不使用 Memoization 是可以的。解决想象中的性能问题是一件真实的事情,所以在我们开始优化之前,请确保您熟悉 React Profiler。
我从下面的文章中得到了这个信息,特别是它解释了 React.memo、useMemo、useCallback、React 纯组件:https ://medium.com/geekculture/great-confusion-about-react-memoization-methods-react-memo- usememo-usecallback-a10ebdd3a316
如果我们的组件渲染成本不高或渲染性能缓慢,那么我们可能不需要像使用 React.memo 那样记住它,在某些情况下,由于客户端要解析更多代码,因此性能会变差。