首页 短视频

React useCallback 和 memo:告别无效渲染,性能优化实战指南

分类:短视频
字数: (1271)
阅读: (8572)
内容摘要:React useCallback 和 memo:告别无效渲染,性能优化实战指南,

在 React 应用开发中,我们经常会遇到组件不必要的重新渲染问题,导致性能下降。 useCallbackmemo 是 React 提供的两个强大的性能优化工具,能够有效地避免这类问题。本文将深入探讨 useCallbackmemo 的底层原理,并通过实际代码示例,分享如何利用它们提升 React 应用的性能。

问题场景重现:组件的无效渲染

考虑一个简单的场景:一个父组件 ParentComponent 包含一个子组件 ChildComponent,父组件维护一个状态 count,并将一个函数 handleClick 传递给子组件。

React useCallback 和 memo:告别无效渲染,性能优化实战指南
import React, { useState } from 'react';

function ChildComponent({ onClick }) {
 console.log('ChildComponent rendered'); // 每次父组件更新都会执行,即使 onClick 没变
 return <button onClick={onClick}>Click me</button>;
}

function ParentComponent() {
 const [count, setCount] = useState(0);

 const handleClick = () => {
 setCount(count + 1);
 };

 return (
 <div>
 <p>Count: {count}</p>
 <ChildComponent onClick={handleClick} />
 <button onClick={() => setCount(count - 1)}>Decrement</button>
 </div>
 );
}

export default ParentComponent;

每次点击父组件的 “Decrement” 按钮,count 状态更新,父组件重新渲染,子组件 ChildComponent 也会跟着重新渲染。但实际上,ChildComponent 接收到的 onClick prop 并没有发生改变,这次重新渲染是无效的。

React useCallback 和 memo:告别无效渲染,性能优化实战指南

useCallback:缓存函数实例

useCallback 是一个 React Hook,它可以缓存函数实例,只有当依赖项发生变化时,才会返回新的函数实例。使用 useCallback 可以避免每次渲染都创建新的函数实例,从而避免不必要的子组件重新渲染。

React useCallback 和 memo:告别无效渲染,性能优化实战指南
import React, { useState, useCallback } from 'react';

function ParentComponent() {
 const [count, setCount] = useState(0);

 // 使用 useCallback 缓存 handleClick 函数
 const handleClick = useCallback(() => {
 setCount(count + 1);
 }, [count]); // 依赖项为 count

 return (
 <div>
 <p>Count: {count}</p>
 <ChildComponent onClick={handleClick} />
 <button onClick={() => setCount(count - 1)}>Decrement</button>
 </div>
 );
}

在这个例子中,我们使用 useCallback 缓存了 handleClick 函数,并将 count 作为依赖项。只有当 count 发生变化时,handleClick 函数才会重新创建。这样,即使父组件重新渲染,只要 count 没有发生变化,handleClick 函数实例就不会改变,ChildComponent 也不会重新渲染。

React useCallback 和 memo:告别无效渲染,性能优化实战指南

memo:缓存组件渲染结果

memo 是一个高阶组件,它可以缓存组件的渲染结果。只有当组件的 props 发生变化时,才会重新渲染组件。memo 相当于 PureComponent 的函数组件版本。我们可以使用 React.memo 包裹 ChildComponent,来缓存它的渲染结果。

import React from 'react';

// 使用 memo 缓存 ChildComponent 的渲染结果
const ChildComponent = React.memo(function ChildComponent({ onClick }) {
 console.log('ChildComponent rendered');
 return <button onClick={onClick}>Click me</button>;
});

export default ChildComponent;

现在,只有当 ChildComponent 的 props 发生变化时,才会重新渲染。结合 useCallback,我们可以避免不必要的子组件重新渲染,从而提升 React 应用的性能。

实战避坑经验总结

  • 过度使用 useCallbackmemo 可能会适得其反:并不是所有的函数和组件都需要缓存,只有当组件的渲染开销比较大,并且 props 频繁更新时,才需要使用 useCallbackmemo。过度使用会增加代码的复杂度,并且可能会降低性能。
  • useCallback 的依赖项一定要写全:如果依赖项没有写全,useCallback 返回的函数实例可能不是最新的,导致意想不到的错误。使用 ESLint 的 exhaustive-deps 规则可以帮助我们检查依赖项是否写全。
  • memo 默认只会浅比较 props:如果 props 是一个复杂对象,浅比较可能无法检测到变化,导致组件没有重新渲染。可以使用 memo 的第二个参数,传入一个自定义的比较函数,来进行深比较。
  • 性能测试是关键:在应用 useCallbackmemo 之后,一定要进行性能测试,确保性能得到了提升。可以使用 React DevTools 的 Profiler 功能来分析组件的渲染性能。可以使用 Chrome 的 Performance 面板,配合宝塔面板监控服务器的 CPU、内存占用情况,评估优化效果。例如,观察 Nginx 的并发连接数是否降低,请求响应时间是否缩短。

通过合理地使用 useCallbackmemo,我们可以有效地优化 React 应用的性能,提升用户体验。在实际开发中,需要根据具体的场景,选择合适的优化策略。

React useCallback 和 memo:告别无效渲染,性能优化实战指南

转载请注明出处: 代码一只喵

本文的链接地址: http://m.acea1.store/article/86023.html

本文最后 发布于2026-04-05 00:55:12,已经过了23天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 芝麻糊 5 天前
    大佬分析得很深入,学习了!请问一下,如果子组件本身也有状态,memo 还能起作用吗?
  • 西红柿鸡蛋面 4 天前
    memo 默认浅比较这个坑我踩过,还好后来发现了,自定义比较函数确实很有用。
  • 咸鱼翻身 6 天前
    React 性能优化一直是个头疼的问题,这篇文章结合实际场景,讲解得很到位,收藏了!
  • 北京炸酱面 1 天前
    大佬分析得很深入,学习了!请问一下,如果子组件本身也有状态,memo 还能起作用吗?