【问题标题】:When to use useMemo and useCallback for performance optimization?何时使用 useMemo 和 useCallback 进行性能优化?
【发布时间】:2021-03-09 05:15:08
【问题描述】:

考虑一下我有这样的例子:

import React, { useMemo, useCallback } from 'react'

const Hello = (props) => {
  const { firstName, lastName } = props
  const fullName = useMemo(() => `${firstName} ${lastName}`, [firstName, lastName])

  const sayHello = useCallback(() => {
    console.log(`Hello, ${fullName}`)
  }, [fullName])

  return (
    // ...
  )
}

export default Hello

基本上我有一个名为Hello的组件,它接收两个道具firstName和lastName,然后我需要根据这两个道具计算fullName并有一个函数sayHello()使用fullName做某事

所以我的问题是:这里有必要使用useMemo() 和useCallback() 进行性能优化吗?似乎过度使用 useMemo() 和 useCallback() 只是为了一点点好处,我不确定这是否会导致潜在的副作用?

【问题讨论】:

  • sayHello 有什么用?这对答案有很大影响。
  • 我认为一般建议只写普通函数,只有当你发现性能有问题时,才使用记忆工具。作为 T.J.状态,这取决于消耗 sayHello 的内容。
  • 正如克劳德所说;如果您将sayHello 传递给一个包含许多项目的列表并使用onClick 会怎样?在每个渲染上传递一个新创建的事件处理程序将导致虚拟 dom 比较失败,React 会将所有项目重新绘制到 DOM。

标签: javascript reactjs react-hooks usecallback react-usememo


【解决方案1】:

在该示例中,useMemo 的使用和 useCallback 的使用的不同答案:

  • useMemo 几乎可以肯定是矫枉过正; sayHello 构建该字符串并没有那么昂贵(相对于创建一个新函数以在每次渲染时传递给 useMemo)。

  • useCallback 的答案取决于sayHello 的使用方式。如果 sayHello 作为 prop 提供给在该 prop 上记忆的组件(例如 PureComponent,直接实现 shouldComponentUpdate 的东西,或者用 React.memo 包装组件的结果),它可以是性能优化以保持sayHello 稳定,如您所展示的那样记忆它,以便您传递给它的组件在它更改时不必重新渲染。但是,如果没有,它可能没有用,不。

我同意Drew Reese:从编写函数开始,然后对您认为性能不佳的代码进行优化。 (尽管在某些情况下,您可能会根据以前的经验采取主动——例如,将您可以记忆的回调传递给数百个纯子组件......)

【讨论】:

  • 请注意,如果我这样做<ListItem key={item.id} onClick={callbackWithUseCallback} item={item} /> 即使ListItem 不是纯的(React.memo、PureComponent、shouldComponentUpdate),当item 不改变时,jsx 会重新创建但虚拟 dom 比较会让 React not 重新渲染 DOM。如果你这样做onClick={()=>'new ref created'},那么即使 ListItem 是纯的,它也会重新创建 jsx 并重新渲染 DOM,因为虚拟 DOM 比较将失败(事件处理程序有一个新的引用)。
  • @HMR - 在这种情况下,“render”意味着组件函数再次运行(如果它是 class 组件,则组件的 render 函数),这是我们试图避免的。 (是的,“render”可以说不是该方法的最佳名称。)这样您就没有运行组件函数/render 方法的开销和虚拟 DOM 比较的开销。确实,即使组件不是纯组件,如果没有任何更改,DOM 也不会更新,如果不是,则需要更多的工作才能到达那里。 :-)
猜你喜欢
  • 2019-11-16
  • 2022-12-18
  • 2022-12-15
  • 2022-12-23
  • 2019-09-20
  • 2020-01-22
  • 1970-01-01
  • 2023-03-25
相关资源
最近更新 更多