ReactHooks使用useMemo和useCallback优化程序性能

React1 个月前05417

当父组件引入子组件以及在更新某一个值的状态的时候,往往会造成一些不必要的浪费,而useMemo和useCallback的出现就是为了减少这种浪费,提高组件的性能,不同点是:useMemo返回的是一个缓存的值,即 memoized 值,而useCallback返回的是一个 memoized 回调函数。

下面我们通过一个实例,来理解下 useMemo的用法。

useMemo 用法

父组件

function App() {
  const [name, setName] = useState('名称')
  const [content,setContent] = useState('内容')
  return (
      <>
        <button onClick={() => setName(new Date().getTime())}>name</button>
        <button onClick={() => setContent(new Date().getTime())}>content</button>
        <Button name={name}>{content}</Button>
      </>
  )
}

子组件

function Button({ name, children }) {
  function changeName(name) {
    console.log('11')
    return name + '改变name的方法'
  }

  const otherName =  changeName(name)
  return (
      <>
        <div>{otherName}</div>
        <div>{children}</div>
      </>

  )
}

熟悉react的同学可以很显然的看出,当我们点击父组件的按钮的时候,子组件的name和children都会发生变化。

注意我们打印console.log的方法。

不管我们是改变name或者content的值,我们发现 changeName的方法都会被调用。
是不是意味着 我们本来只想修改content的值,但是由于name并没有发生变化,所以无需执行对应的changeName方法。但是发现他却执行了。 这是不是就意味着性能的损耗,做了无用功。

下面我们使用useMemo进行优化

优化之后的子组件

function Button({ name, children }) {
  function changeName(name) {
    console.log('11')
    return name + '改变name的方法'
  }

const otherName =  useMemo(()=>changeName(name),[name])
  return (
      <>
        <div>{otherName}</div>
        <div>{children}</div>
      </>

  )
}

export default Button

这个时候我们点击 改变content值的按钮,发现changeName 并没有被调用。
但是点击改变name值按钮的时候,changeName被调用了。
所以我们可以使用useMemo方法 避免无用方法的调用,当然一般我们changName里面可能会使用useState来改变state的值,那是不是就避免了组件的二次渲染。达到了优化性能的目的

useCallback介绍

useCallback 可以说是 useMemo 的语法糖,能用 useCallback 实现的,都可以使用 useMemo, 常用于react的性能优化。在 react 中我们经常面临一个子组件渲染优化的问题,尤其是在向子组件传递函数props时,每次 render 都会创建新函数,导致子组件不必要的渲染,浪费性能,这个时候,就是 useCallback 的用武之地了,useCallback 可以保证,无论 render 多少次,我们的函数都是同一个函数,减小不断创建的开销。

const memoCallback= useCallback(callback,array)

返回一个 memoized 回调函数。

  • callback是一个函数用于处理逻辑
  • array 控制useCallback重新执⾏的数组,array改变时才会重新执⾏useCallback
  1. 不传数组,每次更新都会重新计算
  2. 空数组,只会计算一次
  3. 依赖对应的值,对应的值发生变化重新计算

useCallback返回值是callback本身(useMemo返回的是callback函数的返回值)

useCallback(fn, deps) 相当于 useMemo(() => fn, deps)

useCallback使用

function App () {
  const [ count, setCount ] = useState(0)
  const add = useCallback(() => count + 1, [count])
  return (
    <div>
      点击次数: { count }
      <br/>
      次数加一: { add() }
      <button onClick={() => { setCount(count + 1)}}>点我</button>
    </div>
    )
}
0 条评论

暂无评论