揭秘:如何用React的两大神器斩断性能瓶颈,让你的应用飞起来!

“React Memo 大揭秘:如何彻底改变你的应用性能!“ - 从 memo 来看 react 更新-CSDN博客

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

const Children = ({ name, value }: { name: string; value: number }) => {
  // 每一次子组件更新时,都会触发
  console.log("Children", "render");

  return (
    <div>
      {name}-Children:{value}
    </div>
  );
};

// 模拟大型组件
const BigChildren = ({ handleMultiply }: { handleMultiply: any }) => {
  // 使用for循环 执行代码阻塞0.5s
  for (let i = 0; i < 100000000; i++) {
    for (let j = 0; j < 5; j++) {}
  }

  console.log("BigChildren render");

  return <div onClick={handleMultiply}>Multiply</div>;
};

// 每一次更新都比较前后的 props 是否相同,如果返回 true 就不渲染,返回 false 才渲染。
const MemoChildren = memo(Children);
const MemoBigChildren = memo(BigChildren);

const Counter = () => {
  // 使用 useState 来管理计数状态
  const [count, setCount] = useState(1);

  // 每一次页面更新时,都会触发
  console.log("count:", count, "render");

  const handleAdd = () => {
    // 使用 useState 更新状态,并触发重新渲染
    setCount((prevCount) => prevCount + 1);
  };

  const handleMultiply = () => {
    // 使用 useState 更新状态,并触发重新渲染
    setCount((prevCount) => prevCount * 2);
  };

  const memoHandleMultiply = React.useCallback(handleMultiply, []);

  return (
    <div>
      <div style={{ display: "flex", gap: "6px" }}>
        <p>Count (useState): {count}</p>
        <button type="button" onClick={handleAdd}>
          add
        </button>
      </div>
      {/* 这里你可以尝试切换4种情况,看一下memo的优化效果 */}
      {/* <BigChildren handleMultiply={handleMultiply}></BigChildren> */}
      {/* <BigChildren handleMultiply={memoHandleMultiply}></BigChildren> */}
      {/* <MemoBigChildren handleMultiply={handleMultiply}></MemoBigChildren> */}
      <MemoBigChildren handleMultiply={memoHandleMultiply}></MemoBigChildren>
      <MemoChildren name="useState" value={count}></MemoChildren>
    </div>
  );
};

export default Counter;

  1. 在BigChildren组件中,通过一个双层循环模拟了一个耗时操作,这代表了在实际应用中可能遇到的大型组件或复杂计算,这些操作可能会导致组件渲染变慢。
  2. 使用memo优化:如上篇文章中讲到,memo是React提供的一个高阶组件,用于阻止组件的无谓渲染。通过将Children和BigChildren组件用memo包裹,可以实现仅在组件的props发生变化时才重新渲染的优化效果。
  3. 使用useCallback避免不必要的渲染:在React中,每次组件渲染都会创建新的函数实例,如果这些函数作为props传递给子组件,即使这些函数的实际作用并未改变,子组件也会因为接收到新的props而导致重新渲染。useCallback钩子用于缓存函数,以便跨渲染保持函数实例的一致性。在上述代码中,memoHandleMultiply使用了useCallback来缓存handleMultiply函数,这样即使Counter组件重新渲染,memoHandleMultiply也不会改变,从而避免了MemoBigChildren因接收到新的handleMultiply函数实例而重新渲染。
  4. 代码通过注释提供了四种情况的切换选项,以展示使用memo和useCallback前后性能的对比。当不使用这些优化技术时,即使是不必要的,BigChildren组件也会在每次Counter组件状态更新时重新渲染。而使用了这些技术后,只有在相关props发生变化时,MemoBigChildren才会重新渲染,从而提高了应用的性能。

在实际情况中,我们常常有一个大型组件,它的重渲染比较浪费时间,但是他的props是一些函数,或者通过一些 state 或者父组件的 props 计算出来的值。那么这个时候我们就需要对这些值进行一个缓存,当依赖项不变时,这些值或者函数他的地址就不会改变,那么 memo 进行比较的时候会相等这样就不会触发重新渲染了。

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值