?? 使用 useMemo 和 useCallback 加速 React:告别缓慢的重新渲染!??

2024/9/27 0:03:22

本文主要是介绍?? 使用 useMemo 和 useCallback 加速 React:告别缓慢的重新渲染!??,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

如果你和我一样,你一定爱上了React运行时的流畅感觉……直到它不再流畅!没错,随着你的应用变得越来越大、越来越复杂,你可能会开始注意到一些性能下降的情况。但别担心!React为我们提供了一些很棒的工具useMemouseCallback来保持应用运行得既快又流畅。

在这份指南中,我们将用一种有趣且友好的方式来分解这两个钩子,让你能够轻松优化应用而不会感到压力!

🧐 等等,为什么还要优化?React 不够快吗?

很好的问题!React 通常非常快。但有时,如果你在运行昂贵的计算或通过组件树传递大量函数,事情可能会开始变慢。每当你的应用重新渲染(因为 props 或 state 发生变化时),React 都需要重新做很多事情。

这就轮到 useMemouseCallback 上场了。它们基本上可以让 React “记住” 一些东西,这样 React 就不必重复做不必要的工作了!


🧠 useMemo: 让 React 记住那些难计算的东西!

可以把 useMemo 当作一个聪明的助手。它会记住一个函数的结果,并且只有在重要事情发生变化时才会重新计算。当输入根本没有变化时,为什么还要重新计算呢?完全正确。

基础知识:

    const memoizedValue = useMemo(() => {
      return 计算昂贵的值(a, b);
    }, [a, b]);

进入全屏模式 退出全屏模式

在这个例子中,calculateSomethingExpensive 只有在 ab 发生变化时才会运行。否则,React 会说:“不需要重新做这项工作——我已经在这里保存好了!”

一个有趣的例子:

假设我们正在构建一个计算购物车总价值的组件。每当组件重新渲染时,它都会重新计算总价值。如果你经常购物(我们确实经常购物!),这个计算可能会减慢应用程序的速度:

    function 购物车({ items }) {
      const totalValue = items.reduce((sum, item) => sum + item.price, 0);

      return <div>总价: {totalValue}</div>;
    }

进入全屏模式 退出全屏模式

即使 items 没有改变,我们仍然每次都在做计算!通过 useMemo,我们可以告诉 React 只在 items 数组发生变化时才重新计算:

    function 购物车({ items }) {
      const totalValue = useMemo(() => {
        return items.reduce((sum, item) => sum + item.price, 0);
      }, [items]);

      return <div>总价: {totalValue}</div>;
    }

进入全屏模式 退出全屏模式

Boom!现在你的应用只有在购物车里实际上有了新的东西时才会重新计算。这就像 React 在说:“这个我来搞定。”


&#128293; useCallback: 每秒不再生成新的函数!

现在让我们来谈谈 useCallback。如果说 useMemo 是关于记住值的,那么 useCallback 就是关于记住函数的。当你将一个函数作为属性传递给子组件时,这非常有用。

没有 useCallback,React 会在每次渲染时重新创建你的函数——这可能会导致子组件不必要的重新渲染。我们都知道这有多烦人!

基础知识:

    const memoizedCallback = useCallback(() => {
      doSomething(a, b);
    }, [a, b]);

进入全屏模式 退出全屏模式

这告诉 React 只有在 ab 发生变化时才重新创建 doSomething 函数。如果没有变化,React 就会复用之前的函数!

让我们来分解一下:

这里有一个常见的场景:你有一个父组件将一个 handleClick 函数传递给子组件。但是每次父组件重新渲染时,该函数都会被重新创建,从而迫使子组件也进行重新渲染:

    function 父组件() {
      const handleClick = () => {
        console.log('按钮被点击了!');
      };

      return <子组件 onClick={handleClick} />;
    }

进入全屏模式 退出全屏模式

即使没有任何变化,子组件仍然认为它需要重新渲染,因为handleClick函数每次都是“新的”。

现在,让我们聪明一点,使用 useCallback 来避免这种情况:

    function 父组件() {
      const handleClick = useCallback(() => {
        console.log('按钮被点击了!');
      }, []);

      return <子组件 onClick={handleClick} />;
    }

进入全屏模式 退出全屏模式

太棒了!现在当handleClick函数的依赖发生变化时,它才会改变,而子组件也不会不必要的重新渲染。


&#129300; useMemo vs. useCallback: 有何区别?(剧透:两者都很棒!)

好吧,你现在可能在想,“这两个听起来挺相似的——有什么区别呢?”

  • useMemo: 缓存函数的结果。当你有一些昂贵的计算不需要每次都重新计算时非常有用。
  • useCallback: 缓存函数本身。当你将函数作为props传递并希望避免不必要的重新渲染时非常合适。

快速回顾:

  • 使用 useMemo 来避免不必要的重新计算。
  • 使用 useCallback 来防止在依赖项发生变化之前创建新的函数。

    • *
&#128640; 实际上你应该在什么情况下使用这些钩子?

这里有个黄金法则:不要过度使用 useMemouseCallback。真的!对于大多数应用来说,React 已经足够快了,而处处使用这些钩子可能会增加不必要的复杂性。

何时使用 useMemo:

  • 你在做一些繁重的任务,比如过滤或排序一个大型列表,或者进行复杂的数学计算。

何时使用 useCallback:

  • 你将函数传递给子组件,发现这些组件比必要的渲染次数更多(特别是如果它们被包裹在 React.memo 中)。

在使用这些钩子之前和之后测量性能。如果你注意到速度有所提升,那就太好了!如果没有,也许不值得增加这种额外的复杂性。


&#128561; 坑点:不要成为那样的人!
  • 过度使用:请不要在每个函数或计算上都使用 useMemouseCallback。如果使用过度,实际上会损害性能。只有在需要时才使用 memoization。
  • 依赖项错误:如果你忘记在依赖数组中包含正确的依赖项,你的 memoized 函数可能无法正确更新。始终检查你的函数依赖于哪些变量。

    • *
&#127881; 总结:保持乐趣和速度!

所以这就完了!useMemouseCallback 是保持你的 React 应用程序运行流畅的绝佳工具,但请记住——React 本身已经非常快了。当你需要优化性能时再使用这些钩子,但不要过度使用。简洁才是关键!

有了这些,出去让你的应用变得飞快(同时享受这个过程)


祝你编码愉快!


这篇关于?? 使用 useMemo 和 useCallback 加速 React:告别缓慢的重新渲染!??的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程