React.memo, useMemo y useCallback para optimizar el rendimiento de React

prefacio

Cuando usamos React para desarrollar, a menudo nos encontramos con la situación de que los componentes principales introducen componentes secundarios. Cuando no se realiza ninguna optimización, a menudo provoca una representación repetida innecesaria de los componentes secundarios. Vea un ejemplo simple a continuación

// 例子1:这种情况下,每次父组件更新count值的时候,子组件也会重复渲染

function Child(props){
    console.log('子组件渲染')
    return(
        <div>{props.title}</div>
    )
}
function Parent(){
    const [count, setCount] = useState(1);
    return(
        <div>
            <Child title="我是子组件" />
            <button onClick={() => setCount(count+1)}>add</button>
            <div>count:{count}</div>
        </div>
    )
}

复制代码

React.memo

1. React.memo es un componente de alto nivel, que es bastante similar a React.PureComponent

2. Uso: React.memo(component, Func), el primer parámetro es un componente personalizado y el segundo parámetro es una función para determinar si el componente debe volver a renderizarse. Si se omite el segundo parámetro, se realiza una comparación superficial de los accesorios del componente de forma predeterminada.

// 改造例子1:这种情况下,Child的props经浅比较无变化,则不重复渲染
function Child(props){
    console.log('子组件渲染')
    return(
        <div>{props.title}</div>
    )
}
const NewChild = React.memo(Child, (prevProps, nextProps) => {
      // 自定义对比方法,也可忽略不写
      // return true 则不重新渲染
      // return false 重新渲染
})
function Parent(){
    const [count, setCount] = useState(1);
    return(
        <div>
            <NewChild title="我是子组件" />
            <button onClick={() => setCount(count+1)}>add</button>
            <div>count:{count}</div>
        </div>
    )
}
复制代码

Sin embargo, en algunos casos, el simple hecho de confiar en React.memo para ajustar los subcomponentes provocará una repetición innecesaria de la representación y actualización de los subcomponentes. En este momento, useMemo y useCallback pueden realizar una optimización de rendimiento más detallada. Ver el siguiente ejemplo

// 例子2
function Child({title, onChangeTitle}){
  console.log('子组件渲染')
  return(
      <>
        <div>{title.value}</div>
        <button onClick={() => onChangeTitle('我是新的title')}>change title</button>
      </>
  )
}
const NewChild = React.memo(Child);

function Parent(){
    const [count, setCount] = useState(1);
    const [title, setTitle] = useState('我是子组件');
    const onChangeTitle = (text) => {
        setTitle(text)
    }
    return(
        <div>
            <NewChild title={{value: title}} onChangeTitle={onChangeTitle}>
            <button onClick={() => setCount(count+1)}>add</button>
            <div>count:{count}</div>
        </div>
    )
}
复制代码

En este caso, cada vez que se actualice el componente principal, los valores title y onChangeTitle del componente secundario generarán una nueva dirección de memoria , por lo que incluso si el título no cambia, el componente secundario se volverá a representar y el memo fallará.

useMemo

Ejecutado en el primer renderizado, almacena variables en caché, luego solo vuelve a calcular los valores de memoria cuando cambian las dependencias

useCallback

Ejecutado en el primer procesamiento, almacena en caché la función, después de eso, el caché se actualiza solo cuando cambian las dependencias

//改造例子2
function Child({title, onChangeTitle}){
  console.log('子组件渲染')
  return(
      <>
        <div>{title.value}</div>
        <button onClick={() => onChangeTitle('我是新的title')}>change title</button>
      </>
  )
}
const NewChild = React.memo(Child);

function Parent(){
  const [count, setCount] = useState(1);
  const [title, setTitle] = useState('我是子组件');
  const onChangeTitle = useCallback((text) => {
      setTitle(text)
  },[])
  const memoTitle = useMemo(() => ({value: title}), [title])
  return(
      <div>
          <NewChild title={memoTitle} onChangeTitle={onChangeTitle} />
          <button onClick={() => setCount(count+1)}>add</button>
          <div>count:{count}</div>
      </div>
  )
}
复制代码

Resumir

1. Los usos de useMemo y useCallback son similares. Se ejecutan en la primera representación y luego se vuelven a ejecutar cuando cambian las dependencias. La diferencia es que useMemo devuelve la variable en caché y useCallback devuelve la función en caché.

2. En el proceso de desarrollo real de los componentes comerciales, definitivamente es mucho más complicado que los ejemplos mencionados anteriormente, por lo que hay muchos factores que causan el renderizado repetido innecesario. Necesitamos hacer un buen uso de React.memo, useMemo y useCallback, etc. .para optimizar componentes, y no usar a ciegas

Supongo que te gusta

Origin juejin.im/post/7078881777506320397
Recomendado
Clasificación