我应该将此函数包装在useCallback中吗



我对useCallback的工作原理有相当深入的了解。然而,在我和我的同事中,弄清楚什么时候使用它似乎是主观的。我很好奇其他人对我们目前的困境有什么看法。

想象一下,我们有一个组件,由于选择了某个东西,它正在调度一个动作来进行redux:

const SelectionComponent = props => {
const dispatch = useDispatch()
const handleSelect = (selection) => {
dispatch(actions.updateSelection(selection))
}
return <Select onSelect={handleSelect} ... />
}

我的同事认为,我们应该将handleSelect封装在useCallback中,以确保函数具有稳定的标识,因为它是作为回调传递给子组件的:

const SelectionComponent = props => {
const dispatch = useDispatch()
const handleSelect = useCallback((selection) => {
dispatch(actions.updateSelection(selection))
}, [dispatch])
return <Select onSelect={handleSelect} ... />
}

所以我的问题是,哪一个是更好的解决方案,为什么?

一些注意事项:

  • useDispatch返回一个具有稳定标识的dispatch函数
  • 如果没有useCallback,就不会出现重新转发器或性能问题

编辑

为了澄清,这是一个问题,即当传递给子组件时,我们是否应该在保持稳定身份的基础上对函数进行记忆,即使组件树出于任何原因都不会重新发送。

handleSelect的记忆只有在Select也被记忆的情况下才会产生影响。请记住,当组件重新渲染时,默认情况下也会重新渲染其所有子级(无论其道具是否更改(。

因此,在不知道Select是如何实现的情况下,我们不能真正说useCallback是否真的有任何影响,如果它是";"更好";。

通常,这种类型的优化是不必要的。除非你的Select在某种程度上很复杂或昂贵,否则你可能也不需要记忆。

同样的问题,我只是找到了答案https://github.com/reduxjs/react-redux/issues/1468"dispatch将始终是相同的函数引用。(事实上,在React Redux的早期版本中,传递新的商店引用是被禁止的。我们现在支持在运行时更改它,但实际上你可能不会这么做。(

然而,ESLint规则并不知道这一点——它只知道dispatch不是内置的React hook返回值,因此它可能会更改,因此它告诉您应该将其添加到依赖项数组中,以防它发生更改">

组件重新渲染时,如果其任何属性发生了更改,则会重新渲染其所有子级。这意味着,如果子对象具有与以前相同的属性,则将触发渲染,这是真的,但它实际上不会做出任何更改,也不会花费任何时间。

然而,useCallback依赖性检查也有成本,因此由您决定,使用useCallback的开销是否比重新渲染Select组件便宜。考虑到它还有其他属性,这些属性可能会更改并导致它重新渲染。

我更喜欢记住回调,除非它们被传递到";"本地";组件。因为我不能确定子组件是否不会将此回调用作依赖项。

相关内容

  • 没有找到相关文章

最新更新