1.useCallback

  • 组件多次被调用,多次渲染,性能低
  • demo 可以在git react-Hooks-study/src/compontes/reactTs/useCallback 可以查看详细的useCallback
  • 主要需要注意的地方,一个是react 高阶函数React.memo 应用结合useCallback
学习使用了 React.memo 在 props 或 state 没有变化时,阻止组件的 rerender。
学习了什么是 useCallback,如何使用 useCallback 缓存一个方法,只依赖某几个变量变化才更新,避免了每次传递给子组件的 props 都被更新,最终也是阻止了子组件不必要的 rerender。
import React from "react";

function Count(props: { text: string; count: number }) {
  console.log(`RenderingCount ${props.text}`);
  return (
    <div>
      {props.text} - {props.count}
    </div>
  );
}

export default React.memo(Count);

 const incrementAge = useCallback(() => {
    setAge(age + 1);
  }, [age],);

  const incrementSalary = useCallback(() => {
    setSalary(salary + 1000);
  }, [salary],);

2.useMemo

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
返回一个 memoized 值。 把“创建”函数和依赖项数组作为参数传入 useMemo,它仅会在某个依赖项改变时才重新计算 memoized 值。这种优化有助于避免在每次渲染时都进行高开销的计算。

记住,传入 useMemo 的函数会在渲染期间执行。请不要在这个函数内部执行与渲染无关的操作,诸如副作用这类的操作属于 useEffect 的适用范畴,而不是 useMemo

如果没有提供依赖项数组,useMemo 在每次渲染时都会计算新的值。

你可以把 useMemo 作为性能优化的手段,但不要把它当成语义上的保证。 将来,React 可能会选择“遗忘”以前的一些 memoized 值,并在下次渲染时重新计算它们,比如为离屏组件释放内存。先编写在没有 useMemo 的情况下也可以执行的代码 —— 之后再在你的代码中添加 useMemo,以达到优化性能的目的。

import React, { useState } from 'react'

function Counter() {
  const [counterOne, setCounterOne] = useState(0)
  const [counterTwo, setCounterTwo] = useState(0)

  const incrementOne = () => {
    setCounterOne(counterOne + 1)
  }

  const incrementTwo = () => {
    setCounterTwo(counterTwo + 1)
  }

  const isEven = () => {
    let i = 0
    while (i < 1000000000) i += 1
    return counterOne % 2 === 0
  }

  return (
    <div>
      <button
        onClick={incrementOne}
      >Count One = {counterOne}</button>
      <span>
        {
          isEven() ? 'even' : 'odd'
        }
      </span>
      <br />
      <button
        onClick={incrementTwo}
      >Count Two = {counterTwo}</button>
    </div>
  )
}

export default Counter
useMemo 在性能优化中的作用。通过缓存函数的返回值,避免不必要的调用,从而避免了组件 rerender。
最后有分析了 useMemo 与 useCallback 的区别,即 useMemo 是缓存了函数的返回值,useCallback 是缓存了函数自身。这两个 api 都是性能优化的方法。

个人建议在性能优化上 少用useCallback。 建议使用 #### useRef解决方案


木子喵
492 声望26 粉丝

too young, too naive