我最近决定刷新react的文档,并遇到https://reactjs.org/docs/react-api.html#reactmemo(React.memo)。
乍一看,它似乎是我几乎所有功能组件的不错选择。所以我就这样做了,并在所有这些文件上应用了memo
。
我不确定我是否能够注意到性能的显着提高,但是可以肯定的是它并没有使速度变慢。
因此产生一个问题:默认情况下,我应该将备忘录应用于所有功能部件吗,以防万一我可以捕捉重新渲染很多元素的情况?这个/我需要知道的其他东西有什么缺点吗?
答案 0 :(得分:2)
否,默认情况下,您不应该记住所有功能组件。您应该根据具体情况决定何时进行此操作。
从文档中:
如果给定相同的道具,功能组件呈现相同的结果,则可以将其包装在对React.memo的调用中,以在某些情况下通过记忆结果来提高性能。
想象一下,您给功能组件增加了一些副作用,例如,从Date.now()
读取当前时间。首次使用某些道具调用该组件时,它将按预期工作,但是下次使用这些相同的道具调用时,将使用旧时间。这会导致令人困惑的错误。
例如,如果不太可能使用相同的道具来调用组件,则记忆结果可能会导致更差的性能。毕竟,记忆只是存储对对象的函数调用的结果,其中键是从函数的输入派生的,而值是函数调用的结果。如果您永远不会使用它,为什么还要存储它?
如果您的功能组件不需要花费很多CPU周期来渲染,则任何性能优化都可能会忽略不计。但是现在可以在以后向该组件添加副作用,忘记将其记忆化了,并浪费时间修复产生的错误。
同样,来自文档:
此方法仅作为性能优化存在。不要依靠它来“阻止”渲染,因为这可能会导致错误。
答案 1 :(得分:0)
更简短的解释:
如果 React.memo()
一切都使 React 更加高效和优化,则应将其视为默认行为,而不仅仅是选项(如纯函数)。
基本上,React.memo()
通过比较组件之前和当前的 props 来防止重复渲染。
<Parent>
<Child />
</Parent>
通常,当 Parrent
重新渲染时,默认情况下 Child
也会重新渲染。
对于 React.memo()
,如果在 Child
重新渲染时传递给 Parent
的 props 没有改变,则 Child
不会重新渲染。
这里的问题是:为什么 React 知道传递给 Child
的 props 在当前重新渲染中没有改变?
答案是:React本身要做比较,就是React.memo()
如果比较的时间 > 只是重新渲染整个 Child
组件的时间,它甚至会减慢您的应用的速度。