乐趣区

关于前端:React中memo和useMemo区别和使用

网上的教程看得挺乱的, 还是心愿大家手动打代码, 去体验下, 印象更好

React.memo 和 useMemo 都是缩小组件中不必要的开销, 晋升性能

其中, memo 是子组件自身是否渲染, useMemo 则是子组件 prop 监听函数

memo

memo 很像 shouldComponentUpdate 生命周期还判断组件是否渲染
不应用 memo

const Child = ({name, children}: any) => {function changeName(name: string) {console.log("changeName");
    return name + "扭转 name 的办法";
  }
  console.log("Child 组件更新");
  const otherName = changeName(name);
  return (
    <>
      <div>{otherName}</div>
      <div>{children}</div>
    </>
  );
};

function Parent() {const [count, setCount] = useState(0);
  const [name, setName] = useState("名称");
  return (
    <>
      <div>{count}</div>
      <button id="btn1" onClick={() => setCount(count + 1)}>count</button>
      <button id="btn2" onClick={() => setName(new Date().getTime() + "")}>name</button>
      <Child name={name}></Child>
    </>
  );
}

export default Parent;

点击 btn1, btn2 按钮二者都会触发 Child 了, 都会打印

Child 组件更新
changeName

点击 btn1, Child 没用 count 属性却还是渲染了, 所以就有了 memo
批改 Child.tsx

const Child = React.memo(({name, children}: any) => {function changeName(name: string) {return name + "扭转 name 的办法";}

  console.log("Child 组件更新");

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

点击 btn1, 就不会在触发 Child 了

useMemo

useMemo 更加具体到组件外部的调用办法

const Child = ({name, children}: any) => {function changeName(name: string) {console.log("changeName");
    return name + "扭转 name 的办法";
  }

  console.log("Child 组件更新");

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

function Parent() {const [name, setName] = useState("名称");
  const [content, setContent] = useState("内容");

  return (
    <>
      <button id="btn1" onClick={() => setName(new Date().getTime() + "")}>name</button>
      <button id="btn2" onClick={() => setContent(new Date().getTime() + "")}>content</button>
      <Child name={name}>{content}</Child>
    </>
  );
}

点击 btn1, btn2 按钮二者都会触发 Child 了, 都会打印

Child 组件更新
changeName

点击 btn2 的时候, 因为 Child 从新渲染, 所以导致 changeName 也跟着打印了
然而 btn2 只扭转 content, 没扭转 Child 中 changeName 须要的属性 name,

对此, 咱们心愿扭转 content 的时候, 不触发组件中 changeName 函数, 因为 changeName 只应用到 name 属性, 因而咱们应该应用 useMemo

const Child = ({name, children}: any) => {function changeName(name: string) {console.log("changeName");
    return name + "扭转 name 的办法";
  }
  console.log("Child 组件更新");
  const otherName = useMemo(() => changeName(name), [name]);
  return (
    <>
      <div>{otherName}</div>
      <div>{children}</div>
    </>
  );
};

但咱们点击 btn2 的时候, 只触发了

Child 组件更新
退出移动版