useCallback 与简单函数
useCallback vs simple function
什么时候应该使用useCallback,什么时候应该使用简单的数组函数?
或者也许我不应该使用第二种方法?
const MyCompenent = (props) => {
const handleClick = useCallback(()=>{
//do stuff
})
return(
<SomeCompnent onClick={handleClick} />
)
}
// or
const MyCompenent = (props) => {
return(
<SomeCompnent onClick={()=> {/*do stuff*/}} />
)
}
根据docs,
Pass an inline callback and an array of dependencies. useCallback will return a memoized version of the callback that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. shouldComponentUpdate).
这意味着,给定一个纯函数和依赖项,对于给定的一组参数/依赖项,输出将保持不变。所以它所做的是保存给定集合的输出,如果进行了这样的调用,而不是调用实际函数,直接返回先前计算的值。
在您的示例中,您没有传递任何依赖项。所以它非常类似于一个简单的函数,但有一个额外的包装层。
您可以为处理程序使用命名函数或内联函数。使用哪个属于个人意见,但是我更喜欢使用命名函数,因为它可以保持 JSX 清洁并提供可重用性的可能性。
参考文献:
要补充 Rajesh 的出色答案,它实际上归结为需要对子组件进行多少优化。
根据我们在 React 中部署大型应用程序(数百万用户)的经验,更重要的性能检查是 Profiler(它是在新的 React Dev Tools 中添加的,带有漂亮的火焰图),而不是比 React 的重新渲染,以及网络获取(IE:不必要的获取,错误的 API,或者可能 运行 同时而不是顺序获取)。
React 重新渲染 != DOM 重新渲染
在某些时候,许多开发人员沉迷于 React 的渲染(我相信部分原因是因为可以选择突出显示渲染)。
事实上,Facebook is not so interested in bringing highlights back因为我相信说的混乱。
在我们公司,也有一些开发人员认为某些组件的渲染是瓶颈(在我看来,他们看错了地方)。
但这也是由于缺乏对 React 渲染可以 非常非常便宜 的理解,这与创建或销毁 HTML 节点完全不同变贵了。
他们(和很多人一样)错误地认为渲染是在重新创建 HTML DOM 树,但事实并非如此。
想象一下,在某个时候有人说我们的大部分组件应该是 PureComponents。我们有数百个组件,所以有点吃力!
我们的团队几乎从不使用 PureComponents 或 ReactMemo,但我们的大多数容器即使在重负载下也能正常工作。
因此,回到这一点,是的,在我们对渲染进行昂贵计算的组件中,但最重要的是与 UX 高度耦合的组件,我们决定进行优化。对于日常的 Joe 和 Alice 组件,我们信任 React。
注意: 另外,请注意 React's Development Mode is considerably slower than Production。当我在工作中被提出一些页面 运行 缓慢,并且基准测试是在开发模式下完成的问题时,我感到很惊讶! (问题没有进一步发展,因为生产 运行 绝对没问题)。
什么时候应该使用useCallback,什么时候应该使用简单的数组函数? 或者也许我不应该使用第二种方法?
const MyCompenent = (props) => {
const handleClick = useCallback(()=>{
//do stuff
})
return(
<SomeCompnent onClick={handleClick} />
)
}
// or
const MyCompenent = (props) => {
return(
<SomeCompnent onClick={()=> {/*do stuff*/}} />
)
}
根据docs,
Pass an inline callback and an array of dependencies. useCallback will return a memoized version of the callback that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. shouldComponentUpdate).
这意味着,给定一个纯函数和依赖项,对于给定的一组参数/依赖项,输出将保持不变。所以它所做的是保存给定集合的输出,如果进行了这样的调用,而不是调用实际函数,直接返回先前计算的值。
在您的示例中,您没有传递任何依赖项。所以它非常类似于一个简单的函数,但有一个额外的包装层。
您可以为处理程序使用命名函数或内联函数。使用哪个属于个人意见,但是我更喜欢使用命名函数,因为它可以保持 JSX 清洁并提供可重用性的可能性。
参考文献:
要补充 Rajesh 的出色答案,它实际上归结为需要对子组件进行多少优化。
根据我们在 React 中部署大型应用程序(数百万用户)的经验,更重要的性能检查是 Profiler(它是在新的 React Dev Tools 中添加的,带有漂亮的火焰图),而不是比 React 的重新渲染,以及网络获取(IE:不必要的获取,错误的 API,或者可能 运行 同时而不是顺序获取)。
React 重新渲染 != DOM 重新渲染
在某些时候,许多开发人员沉迷于 React 的渲染(我相信部分原因是因为可以选择突出显示渲染)。
事实上,Facebook is not so interested in bringing highlights back因为我相信说的混乱。
在我们公司,也有一些开发人员认为某些组件的渲染是瓶颈(在我看来,他们看错了地方)。
但这也是由于缺乏对 React 渲染可以 非常非常便宜 的理解,这与创建或销毁 HTML 节点完全不同变贵了。
他们(和很多人一样)错误地认为渲染是在重新创建 HTML DOM 树,但事实并非如此。
想象一下,在某个时候有人说我们的大部分组件应该是 PureComponents。我们有数百个组件,所以有点吃力!
我们的团队几乎从不使用 PureComponents 或 ReactMemo,但我们的大多数容器即使在重负载下也能正常工作。
因此,回到这一点,是的,在我们对渲染进行昂贵计算的组件中,但最重要的是与 UX 高度耦合的组件,我们决定进行优化。对于日常的 Joe 和 Alice 组件,我们信任 React。
注意: 另外,请注意 React's Development Mode is considerably slower than Production。当我在工作中被提出一些页面 运行 缓慢,并且基准测试是在开发模式下完成的问题时,我感到很惊讶! (问题没有进一步发展,因为生产 运行 绝对没问题)。