Kei*_*ter 26 javascript reactjs
我最近一直在玩React 16.6.0并且我喜欢React Memo的想法,但我一直无法找到任何关于最适合实现它的场景.React docs(https://reactjs.org/docs/react-api.html#reactmemo)似乎没有暗示将其抛在所有功能组件上的任何含义.因为它需要进行浅层比较以确定是否需要重新渲染,是否会出现对性能产生负面影响的情况?像这样的情况似乎是实施的明显选择:
// NameComponent.js
import React from "react";
const NameComponent = ({ name }) => <div>{name}</div>;
export default React.memo(NameComponent);
// CountComponent.js
import React from "react";
const CountComponent = ({ count }) => <div>{count}</div>;
export default CountComponent;
// App.js
import React from "react";
import NameComponent from "./NameComponent";
import CountComponent from "./CountComponent";
class App extends Component {
state = {
name: "Keith",
count: 0
};
handleClick = e => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<NameComponent name={this.state.name} />
<CountComponent count={this.state.count} />
<button onClick={this.handleClick}>Add Count</button>
</div>
);
}
}
Run Code Online (Sandbox Code Playgroud)
因为在这种情况下名称永远不会改变,所以记忆是有意义的.但道具经常变化的情况怎么样?如果我添加了另一个在状态中更改了其他内容并触发重新渲染的按钮,如果在备忘录中包装CountComponent是有意义的,即使这个组件的设计意图经常更新,该怎么办?
我想我的主要问题是只要一切都保持纯净,是否有一种情况不能用React Memo包装功能组件?
Але*_*нин 42
React.memo
LITERALLY,因为比较 Component 返回的树总是比比较一对props
属性更昂贵所以不要听任何人的,把所有的功能组件都包装在React.memo
. React.memo
原本打算内置到功能组件的核心中,但由于失去了向后兼容性,默认情况下不使用。(因为它从表面上比较了对象,并且您可能正在使用组件中子对象的嵌套属性)=)
就是这样,这是 React 不自动使用备忘录的唯一原因。=)
事实上,他们可以制作 17.0.0 版本,这将打破向后兼容性,并制作React.memo
默认值,并制作某种功能来取消此行为,例如React.deepProps
=)
别听理论家了,伙计们 =) 规则很简单:
如果您的组件使用 DEEP COMPARING PROPS,则不要使用备忘录,否则始终使用它,比较两个对象总是比调用React.createElement()
和比较两个树、创建 FiberNode 等更便宜。
理论家谈论他们自己不知道的事情,他们没有分析过反应代码,他们不了解 FRP,也不了解他们的建议 =)
PS 如果您的组件使用children
prop,React.memo
将无法工作,因为children
prop 总是会创建一个新数组。但是最好不要管这个,即使是这样的组件也应该被包裹在 中React.memo
,因为计算资源可以忽略不计。
for*_*d04 19
是否会出现对性能产生负面影响的情况?
是的。如果所有组件都被React.memo
.
在许多情况下不需要它。要尝试使用性能关键组件,请先进行一些测量,添加记忆,然后再次测量以查看增加的复杂性是否值得。
React.memo
多少?记忆化组件将旧组件与新闻道具进行比较,以决定是否重新渲染 -每个渲染周期。
在父组件中的 props/state 更改之后,普通组件不关心并且只是渲染。
看一下 ReactshallowEqual
实现,它在updateMemoComponent
.
React memo
?没有硬性规定。React.memo
负面影响的事情:
广告 1:在这种情况下,React.memo
无法阻止重新渲染,但必须进行额外的计算。
广告 2:就渲染、协调、DOM 更改和副作用成本而言,对于“简单”组件而言,增加的比较成本是不值得的。
广告3:道具越多,计算越多。您还可以传入更复杂的自定义比较器。
React.memo
?它只检查道具,而不是从内部检查上下文更改或状态更改。React.memo
如果 memoized 组件具有 non-primitive ,则也是无用的children
。useMemo
可以memo
在这里补充,例如:
// inside React.memo component
const ctxVal = useContext(MyContext); // context change normally trigger re-render
return useMemo(() => <Child />, [customDep]) // prevent re-render of children
Run Code Online (Sandbox Code Playgroud)
同样的问题有一个通过在GitHub上做出反应问题跟踪markerikson答案。它比这里的答案得到了更多的赞许。
我认为相同的一般建议适用于
React.memo
因为它为shouldComponentUpdate
和PureComponent
:做比较,确实有小的成本,而且也场景中的分量永远不会正确memoize的(尤其是如果它使用的props.children
)。所以,不要只是自动地把所有东西都包装起来。查看您的应用程序在生产模式下的行为,使用 React 的分析构建和 DevTools 分析器来查看瓶颈所在,并有策略地使用这些工具来优化组件树中真正受益于这些优化的部分。
所有反应组件均实施该shouldComponentUpdate()
方法。默认情况下(components扩展React.Component
),始终返回true。记忆组件(通过React.memo
功能组件或扩展React.PureComponent
类组件)的方式引入的更改是shouldComponentUpdate()
方法的实现-对状态和道具进行了浅层比较。
纵观文档上的组件生命周期方法,shouldComponentUpdate()
则总是调用之前渲染发生,这意味着记忆一个组件将包括在每次更新这个附加浅层比较。
考虑到这一点,对组件进行记忆确实具有性能影响,并且应通过对应用程序进行性能分析并确定其在使用或不使用记忆的情况下是否更好来确定这些影响的程度。
要回答您的问题,我不认为应该或不应该记住组件有明确的规则,但是我认为应采用与决定是否应重写时相同的原则shouldComponentUpdate()
:通过建议的性能分析工具查找性能问题并确定您是否需要优化组件。
The idea is to avoid using memoization, for data which has the possibility of changing very often. As stated in the blog, this also includes callbacks which depends on such types of data. For example functions such as
<Foo onClick={() => handle(visitCount)}/>
我真的很喜欢这本简单的读物。这些例子都很棒。https://dmitripavlutin.com/use-react-memo-wisely/
归档时间: |
|
查看次数: |
4310 次 |
最近记录: |