我已经阅读到,使用箭头函数内联会在每个重新渲染的组件上重新创建该函数,从而导致性能问题。
在我的代码中,我遇到这种情况
render() {
return (
<View
onLayout={(event) => {
this.itemHeights[index] = event.nativeEvent.layout.height;
}}
>
...
)
}
我曾想过做这样的事情以获得更好的性能:
getItemHeight = (index, {nativeEvent: {layout: {height}}}) => this.itemHeights[index] = event.nativeEvent.layout.height;
render() {
return (
<View
onLayout={(event) => getItemHeight(index, event)}
>
...
)
}
但是我不确定这是否更好...我必须在内联函数中调用一个函数。我这样做是因为我需要参数索引,所以我做不到:
<View
onLayout={getItemHeight}
>
我知道这可能并不太昂贵,但是对于我的用例来说,这是非常昂贵的,因为我必须即时重新渲染项目。
有什么想法吗?
答案 0 :(得分:2)
首先,我认为您在这里混淆了两件事。 函数的声明与函数的执行有所不同。
该组件也不会一直重新渲染,只是因为在render函数return中重新声明了一个函数。
在函数的声明与其执行之间的性能影响之间也存在巨大差异。
因此,在第一个示例中,您正在做的是为View
组件声明一个函数。基本上,这会重置onLayout
道具的值,因为内联函数不是参照稳定的。
~~在第二个示例中(我认为这是一个类组件),您使用的是参照稳定函数,因此onLayout
的prop值保持不变。~~
更新:实际上这是不对的,我不好。您仍在使用不稳定函数。但是您可以像这样将其作为班级成员提出来:
public getItemHeight(index, {nativeEvent: {layout: {height}}}) {
this.itemHeights[index] = event.nativeEvent.layout.height;
}
// ...
// ... inside the render function:
return {
<View onLayout={this.getItemHeight}></View>
}
但是我不确定这是否更好...我必须在内联函数中调用一个函数。我这样做是因为我需要参数索引,所以我做不到:
实际上,这种说法是不正确的。您还可以使用上面定义的函数检索索引。 使用此代码,您只是为prop提供了对要由回调调用的函数的引用。这将很好地填充参数。
当属性或状态发生更改时,组件将重新呈现。
因此,在您的第一个示例中,View
组件仅在必须重新渲染父组件时才会重新渲染。因此,父级渲染并评估其子组件。这确实会触发View
组件的渲染功能,并将功能换成onLayout
。
在第二个示例中(考虑到上面建议的代码更改),View
组件不会触发其渲染功能,因为onLayout
的prop值未更改。
但这并不意味着您的第一个示例必然导致DOM更改并重新绘制(这是React内部的另一种算法)。 DOM更改将是真正昂贵的部分。
Rerender是React在内部运行的进程。 React只是触发了必须重新渲染的组件的渲染功能。但是只有在生成的DOM与以前不同的情况下,才会在运行时在实际页面内进行重新绘制。
您可以在React Docs中进一步了解此内容:https://reactjs.org/docs/reconciliation.html
我认为您不应该过早地优化此类内容。它会使代码更加膨胀,并引入并非总是必需的复杂性。
这里也有一个完整的部分:https://reactjs.org/docs/optimizing-performance.html#avoid-reconciliation
如果不消耗您的性能,为什么还要麻烦进行微优化呢? 仅仅因为您阅读到每次都会重新创建内联函数(顺便说一句,这也适用于非箭头函数。正是内联声明使它每次都重新创建),因此每次都会渲染函数,这并不总是意味着React必须重新粉刷或者对性能有很大影响。
因此,即使在没有问题的情况下,也不要过早地在小小的性能提升上摆弄。
基于React的应用程序是巨大的代码野兽。一旦遇到性能问题,就会有很多大问题需要解决。