我今天开始使用新的linter(tslint-react),它给了我以下警告:
"由于渲染性能影响,Lambdas在JSX属性中被禁止"
我知道这会导致每个渲染都创建一个新函数.而且它可以触发不需要的重新渲染,因为子组件会认为它的道具已经改变了.
但我的问题是,如何将参数传递给循环内的事件处理程序:
customers.map( c => <Btn onClick={ () => this.deleteCust(c.id) } /> );
Run Code Online (Sandbox Code Playgroud)
Sul*_*han 54
绝对不是反模式.
Lambdas(箭头函数)对渲染性能没有影响.
唯一有影响的是实施shouldComponentUpdate.true默认情况下,此函数返回,这意味着始终呈现组件.这意味着即使道具没有改变,组件仍然会再次渲染.这是默认行为.
如果不实现,将箭头函数更改为绑定方法将无法提高性能shouldComponentUpdate.
确实,不使用箭头函数可以简化实现,shouldComponentUpdate它们不应该使用,PureComponent但它们不是反模式.它们可以简化许多模式,例如在为函数添加其他参数时(例如,在您的示例中您正在执行的操作).
另请注意,React具有无状态组件,甚至无法实现shouldComponentUpdate,因此始终呈现它们.
在实际发现性能问题之前,请不要考虑性能影响.
小智 5
据我所知,即使您不使用React.PureComponentor ,它也会对性能产生影响useMemo。当您在组件的 prop(JSX 属性)中定义匿名箭头函数(Lambda)时,在每个渲染上都会创建相同的函数,因此 JS 引擎无法重用它。这种娱乐不会降低性能,因为 JavaScript 的引擎垃圾收集器必须收集那些不必要的功能。
还有其他几种方法的行为相同。看看下面的例子:
#1 Lamba approach
customers.map( c => <Btn onClick={ () => this.deleteCust(c.id) } /> );
#2 bind apprach
customers.map( c => <Btn onClick={ this.deleteCust.bind(this, c.id) } /> );
#3 call approach
customers.map( c => <Btn onClick={ this.deleteCust.call(this, c.id) } /> );
#4 apply approach
customers.map( c => <Btn onClick={ this.deleteCust.apply(this, [c.id]) } /> );
Run Code Online (Sandbox Code Playgroud)
我会说推荐的方法是在被映射的组件内创建一个单独的函数。让我们稍微修改一下您的示例:
const Btn = ({ clicked, customer }) => {
const buttonClickHandler = () => {
clicked(customer.id)
}
return <button onClick={buttonClickHandler}>Click me!</button>
}
const App = () => {
return (
<App>
{ customers.map(c => <Btn customer={c} clicked={deleteCust} />) }
</App>
)
}
Run Code Online (Sandbox Code Playgroud)
所以现在,由于我们在常量中使用函数表达式而不是匿名函数(不能重用),因此 React 不会在每个新组件重新渲染时重新创建新函数,垃圾收集器可以暂时停止!
| 归档时间: |
|
| 查看次数: |
8428 次 |
| 最近记录: |