:::info

  1. useCallback目的:实际是为了性能的优化。
  2. 使用场景:useCallback在什么时候进行使用?

场景:在将一个组件中的函数,传递给子元素回调使用时,使用useCallback对函数进行处理。

  1. 如何进行性能的优化?

useCallback会返回一个函数的memorized(有记忆的)值
在依赖不变的情况下,多次定义的时候,返回值是相同的 :::

  1. // useCallback的使用方式
  2. const memorixedCallback = useCallback(
  3. () => {
  4. doSomething(a, b),
  5. }, [a, b])

1、错误的使用场景

  1. import React, { useState, useCallback } from 'react'
  2. export default function UseCallbackHookDemo() {
  3. const [count, setCount] = useState(100)
  4. // 增加
  5. const increment = () => {
  6. console.log('执行increment函数');
  7. setCount(count + 1)
  8. }
  9. // 减少 实际上并没有进行太多的性能优化 实际上每次返回的都是同一个函数 对函数进行了相应的缓存 重新渲染的时候进行了浅层比较
  10. const decrement = useCallback(() => {
  11. console.log('执行decrement函数');
  12. setCount(count - 1)
  13. }, [count])
  14. return (
  15. <div>
  16. <h2>{ count }</h2>
  17. <button onClick={ increment }>+1</button>
  18. <button onClick={ decrement }>-1</button>
  19. </div>
  20. )
  21. }

上面的写法,实际上并没有进行太多的性能优化,useCallback回调函数中,我们传入一个函数作为参数,useCallback实际上会返回一个函数的memoized(有记忆)的值;在依赖不变时,多次定义的时候,返回值是相等的。

2、正确的使用场景

  1. # 配置子组件的memo性能优化进行使用
  2. import React, { useState, useCallback, memo } from 'react'
  3. // 定义子组件 使用memo进行相应的包裹
  4. const HYButton = memo((props) => {
  5. // 返回dom结构
  6. console.log(props.name, '组件渲染了');
  7. return <button onClick={ props.increment }>+1</button>
  8. })
  9. export default function UseCallbackHookDemo() {
  10. // 定义状态
  11. const [count, setCount] = useState(100)
  12. // 依赖的其他的状态
  13. const [show, setShow] = useState(true)
  14. // 增加
  15. const increment1 = () => {
  16. console.log('执行increment1函数');
  17. setCount(count + 1)
  18. }
  19. // 减少 使用useCallback进行了性能优化
  20. const increment2 = useCallback(() => {
  21. console.log('执行increment2函数');
  22. setCount(count + 1)
  23. }, [count])
  24. return (
  25. <div>
  26. <h2>{ count }</h2>
  27. <HYButton name="increment1" increment={increment1} />
  28. <hr/>
  29. <HYButton name="increment2" increment={increment2} />
  30. <hr/>
  31. <button onClick={ e => setShow(!show) }>修改组件内的状态</button>
  32. </div>
  33. )
  34. }