React中useMemo和useCallback的区别

一句话来解释,useMemo是缓存值的,useCallback是缓存函数的。
一、useMemo:

接收两个参数,第一个参数是个函数,第二个是依赖项。返回一个memoized值,只有当它的某个依赖项改变时才重新计算 memoized 值,初始化的时候也会调用一次,这种优化有助于避免在每次渲染时都进行高开销的计算。

import React, {
    
     useState, useMemo } from 'react';

export default function hook() {
    
    

  const [count, setCount] = useState(1)
  const [total, setTotal] = useState(1)


  const memoizedValue = useMemo(() => {
    
    
    console.log("只有total变了我才会变")
    // 返回的值是total+1
    return total + 1
  }, [total]);


  return (
    <div>
      <button onClick={
    
    () => setCount(count + 1)}>count + 1</button>
      <button onClick={
    
    () => setTotal(total + 1)}>total + 1</button>
      <div>count is {
    
    count}</div>
      <div>total is {
    
    total}</div>
      <div>memoizedValue is {
    
    memoizedValue}</div>
    </div>
  )
}

二、useCallback

接收两个参数,第一个参数是个函数,第二个是依赖项。返回一个memoized函数,依赖项不变的情况下,memoizedCallback的引用不变。即:useCallback会被缓存,从而达到渲染性能优化的目的。

父组件:

export default function LearnUseCallBack() {
    
    
  const [num, setNum] = useState(1);
  const [count, setCount] = useState(1);
  
  const add = useCallback(() => {
    
    
    console.log("你好");
    setNum(num + 1);
  }, [count]);

  return (
    <div>
      <div>缓存函数</div>
      <button onClick={
    
    add}>num + 1</button>
      <button onClick={
    
    () => setCount(count + 1)}>count + 1</button>
      num ==> {
    
    num}
      count ==> {
    
    count}
      <ChildComponent add={
    
    add}></ChildComponent>
    </div>
  );
}

子组件:

import React, {
    
     useState, useCallback } from "react";

// react.memo会做一层浅比较

/**
 * 因为我们每次触发render 都会重新执行一遍当前函数
 * 所以说,我们的方法会重新赋值,react.memo时进行浅比较
 * 重新赋值的方法和之前的方法,引用不一样,所以react.memo
 * 会认为是一个新的对象,所以会重新渲染
 */
const ChildComponent = React.memo((props) => {
    
    
  console.log("每次render都会触发吗?", props);
  return (
    <div>
      <div>你好我是子组件</div>
    </div>
  );
});

注:若add方法不被缓存,因为add是引用类型,则组件刷新时add函数每次渲染时都指向不同的引用类型,若将add传给子组件,即使子组件使用了memo包裹,子组件还是每次都会刷新的,影响性能!我们只希望与子组件相关的值变化了之后子组件才去重新渲染。

猜你喜欢

转载自blog.csdn.net/qq_42931285/article/details/131840921
今日推荐