React useCallback 性能学习

本文探讨了在React ClassComponent和FunctionComponent中如何优化函数引用,以减少不必要的组件重渲染。重点讲解了useCallback在FunctionComponent中的作用,以及当存在依赖关系时可能引发的复杂性和潜在Bug。通过示例展示了如何正确和错误地使用useCallback,强调了维护引用一致性和管理依赖关系的重要性。
摘要由CSDN通过智能技术生成

在 Class Component 中我们常常把函数绑在this上,保持其的唯一引用,以减少子组件不必要的重渲染。

class App {
  constructor() {
    // 方法一
    this.onClick = this.onClick.bind(this)
  }
  onClick() {
    console.log('I am `onClick`')
  }

  // 方法二
  onChange = () => {}

  render() {
    return (
      <Sub onClick={this.onClick} onChange={this.onChange} />
    )
  }
}

在 Function Component 中对应的方案即 useCallback :

// ✅ 有效优化
function App() {
  const onClick = useCallback(() => {
    console.log('I am `onClick`')
  }, [])

  return (<Sub onClick={onClick} />)
}

// ❌ 错误示范,`onClick` 在每次 Render 中都是全新的,<Sub> 会因此重渲染
function App() {
  // ... some states
  const onClick = () => {
    console.log('I am `onClick`')
  }

  return (<Sub onClick={onClick} />)
}

useCallback可以在多次重渲染中仍然保持函数的引用, 第2行的onClick也始终是同一个,从而避免了子组件 <Sub> 的重渲染。

无限套娃✓[2]

相比较未使用useCallback带来的性能问题,真正麻烦的是useCallback带来的引用依赖问题。

// 当你决定引入 `useCallback` 来解决重复渲染问题
function App() {
  // 请求 A 所需要的参数
  const [a1, setA1] = useState('')
  const [a2, setA2] = useState('')
  // 请求 B 所需要的参数
  const [b1, setB1] = useState('')
  const [b2, setB2] = useState('')

  // 请求 A,并处理返回结果
  const reqA = useCallback(() => {
    requestA(a1, a2)
  }, [a1, a2])

  // 请求 A、B,并处理返回结果
  const reqB = useCallback(() => {
    reqA()                                           // `reqA`的引用始终是最开始的那个,
    requestB(b1, b2)                       // 当`a1`,`a2`变化后`reqB`中的`reqA`其实是过时的。
  }, [b1, b2])                   // 当然,把`reqA`加到`reqB`的依赖数组里不就好了?
                                                             // 但你在调用`reqA`这个函数的时候,
                                                                 // 你怎么知道「应该」要加到依赖数组里呢?
  return (
    <>
      <Comp onClick={reqA}></Comp>
      <Comp onClick={reqB}></Comp>
    </>
  )
}

从上面示例可以看到,当useCallback之前存在依赖关系时,它们的引用维护也变得复杂。调用某个函数时要小心翼翼,你需要考虑它有没有引用过时的问题,如有遗漏又没有将其加入依赖数组,就会产生
Bug。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值