惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Last Week in AI
Last Week in AI
C
CERT Recently Published Vulnerability Notes
博客园 - 叶小钗
大猫的无限游戏
大猫的无限游戏
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
月光博客
月光博客
T
Tailwind CSS Blog
博客园 - 三生石上(FineUI控件)
Jina AI
Jina AI
S
SegmentFault 最新的问题
人人都是产品经理
人人都是产品经理
Hugging Face - Blog
Hugging Face - Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
WordPress大学
WordPress大学
J
Java Code Geeks
V
Visual Studio Blog
腾讯CDC
博客园 - 【当耐特】
博客园 - 司徒正美
小众软件
小众软件
宝玉的分享
宝玉的分享
博客园 - Franky
量子位
有赞技术团队
有赞技术团队
The Cloudflare Blog
Apple Machine Learning Research
Apple Machine Learning Research
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网
美团技术团队
阮一峰的网络日志
阮一峰的网络日志
酷 壳 – CoolShell
酷 壳 – CoolShell
N
News | PayPal Newsroom
D
Docker
Google Online Security Blog
Google Online Security Blog
博客园 - 聂微东
A
About on SuperTechFans
S
Security Affairs
N
News and Events Feed by Topic
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
S
Securelist
T
The Exploit Database - CXSecurity.com
爱范儿
爱范儿
MyScale Blog
MyScale Blog
V
Vulnerabilities – Threatpost
S
Security @ Cisco Blogs
T
Threatpost
Scott Helme
Scott Helme
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Application and Cybersecurity Blog
Application and Cybersecurity Blog
P
Palo Alto Networks Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
What is React memo? How to improve React performance
Hugo Naili · 2026-04-28 · via DEV Community

React memo is a powerful feature that improves the performance of your React applications by letting you skip the re-rendering of components that haven't changed.

This article explains how React memo works and how to use it. It also includes use cases and code examples that you can adapt for use in your own React code to make sure that your applications are as fast and efficient as possible.

What is React memo?

Memoization is a programming technique that improves performance by caching the results of a function. Code that implements memoization checks the result of a function each time it is called to see if it can serve the cached result and avoid recomputation.

In the context of React, this means storing the results of rendering a component to avoid excessive re-renders. React memo is a component that allows you to wrap React components and memoize them based on their properties (props). This means that components wrapped in a memo will not be re-rendered if their properties have not changed.

How React memo works

Typically in React, when the state is updated in a parent component, this will trigger a re-render of that component along with any of its child components, even if only some of them rely on the updated state. This can lead to poor performance, especially if some of those components make API calls or perform complex calculations.

This is solved by using React memo: When you wrap one of your components with a memo component, it will shallowly compare its current props to its previous ones, and if there is no change in the props, React will skip re-rendering that component and continue to use the existing result (as it was in the previous virtual DOM).

For example, if you have a React parent component that displays the value of the U.S. dollar in different currencies (each currency conversion being in its own child component), each time the state of the parent component is updated with new currency data, every child component is re-drawn — even if the conversion rate hasn't changed. By wrapping each child component with memo, only those where the calculated value has actually changed will be redrawn, improving performance.

Shallow vs. deep comparison

Shallow comparison – If a prop is a primitive (string or number), React memo will check if the new value is different from the old one. If a prop is an object or an array, React memo will only compare the memory reference; even if the contents are the same but the reference has changed, it will consider them different and trigger a re-render.

Deep comparison – If a prop is complex, such as an array or object, comparison would require checking every nested value within to ensure all properties are equal to the old values. While this would provide an exact match, it’s computationally expensive and can be slower than the actual re-renders you are trying to prevent. Deep comparison should be avoided by using composition-based patterns to move the state closer to where it’s needed, minimizing the need for complex prop comparisons.

The benefits of using React memo to optimize your components include:

  • Preventing unnecessary re-renders and avoiding redundant updates.
  • Improving performance.
  • Optimizing expensive and complex components.
  • Enhancing the user experience.

As memo is simple to implement by wrapping your existing React components, it is an effective way to improve the efficiency of your apps without significantly reworking them.

How to use React memo (demo)

Now that you know what React memo is and how it works, let's take a look at some code and how you can use it in an application.

In your React project, create a parent component:

import React, { useState, useEffect } from "react";
import ChildComponent from './ChildComponent.jsx'

const ParentComponent = () => {
  const [cardData, setCardData] = useState();
  const [clicked, setClicked] = useState([]);

  useEffect(() => {
    const data = Array.from({ length: 5000 }, (_, index) => ({
      id: index + 1,
      name: `Card ${index + 1}`,
    }));

    setCardData(data);
  }, []);

  const pushItem = (id) => {
    setClicked(() => [{ id }]);
  };

  const renderWithoutMemo = () => {
    const renderedComponents = cardData?.map((card, index) => {
      return (
        <ChildComponent
          key={index}
          name={card.name}
          onClick={pushItem}
          id={card.id}
          handleClick={pushItem}
          isClicked={clicked.some((click) => click.id === card.id)}
        />
      );
    });

    return renderedComponents;
  };

  return (
    <div>
      <div
        style={{
          display: "flex",
          boxSizing: "border-box",
          flexWrap: "wrap",
        }}
      >
        {renderWithoutMemo()}
      </div>
    </div>
  );
};

export default ParentComponent;

Enter fullscreen mode Exit fullscreen mode

Here the component is initialized by creating some mock data, which will render out a list of child components. With 5,000 components, other optimization techniques could be used here (pagination, for example), but this is just to demonstrate a clearly noticeable performance lag.

This component also includes some functionality that allows the user to click a child component from the list that will add its id to an array. This is checked later to decide if it has been clicked or not.

Next, create a child component:

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

const ChildComponent = ({ name, handleClick, isClicked, id }) => {
  console.log("rendering - ", name);

  const calculatePrimes = (num) => {
    const primes = [];

    for (let i = 2; primes.length < num; i++) {
      let isPrime = true;
      for (let j = 2; j < i; j++) {
        if (i % j === 0) {
          isPrime = false;
          break;
        }
      }
      if (isPrime) {
        primes.push(i);
      }
    }
    return primes;
  };

  const primeNumbers = calculatePrimes(5);

  return (
    <div
      style={{
        backgroundColor: isClicked ? "green" : "#f9f9f9",
        border: "1px solid black",
        padding: "5px",
        margin: "5px",
        cursor: "pointer"
      }}
      onClick={() => handleClick(id)}
    >
      <h2 className="name">{name}</h2>
      <div>
        <ul>
          {primeNumbers.map((prime) => (
            <li style={{listStyle: "none"}} key={prime}>{prime}</li>
          ))}
        </ul>
      </div>
    </div>
  );
};

export default ChildComponent;

Enter fullscreen mode Exit fullscreen mode

This is just a simple card component with some code to simulate some sort of expensive computation in each list item.

Now, if you run the application, you will be able to see a noticeable delay in performance when you click a card to change its color. If you open up the console window in your browser, you will also be able to see that each child component logs a message every time you click, showing that updating one component is triggering a re-render for all children.

Now let's add the fix with React memo. Add the below code in App.js above the ParentComponent.

const MemoizedChildComponent = React.memo(
  ChildComponent,
  (prevProps, nextProps) => {
    return prevProps.isClicked === nextProps.isClicked;
  },
);

Enter fullscreen mode Exit fullscreen mode

Create a React memo component by wrapping the child in the React.memo component. By default, React.memo does a shallow comparison of props. This would normally be sufficient, but because the prop isClicked is generated dynamically (by using .some to generate a boolean), you have to pass a second argument to React.memo with an equality check function, allowing you to customize the way properties are checked. This function opens up the possibility to check objects deeply.

This is one of the common pitfalls with using React memo. The bottom line should be to either ensure that comparison props are simple values such as numbers or strings, or use a custom equality check for complex props.

Now add the following function above the renderWithoutMemo function:

const renderWithMemo = () => {
  const renderedComponents = cardData?.map((card, index) => (
    <MemoizedChildComponent
      key={index}
      name={card.name}
      onClick={pushItem}
      id={card.id}
      handleClick={pushItem}
      isClicked={clicked.some((click) => click.id === card.id)}
    />
  ));

  return renderedComponents;
};

Enter fullscreen mode Exit fullscreen mode

In the return statement, remove the current renderwithoutMemo() and replace it with renderWithMemo(). Now, if you refresh the application, you should see a notable improvement in the load speed when you click on a card. Also, in the console, you will only see logs from the cards you click on, showing that the other child components have been memoized. The only components being re-rendered now are the components whose props have changed.

Here you can access a working demo of the application where you can switch between renderWithMemo() and renderWithoutMemo() to see the performance lag.

When to use React memo

It is considered best practice to use React memo in the following scenarios:

  • Frequent prop changes: If the props of a parent component change frequently but the output of a child component stays the same.

  • Expensive rendering: If you have some complex calculation going on inside a component.

  • Large list of components: If you have a large list of components, especially if the props are changing frequently in a parent component or you have expensive computation inside each child component.

  • Pure function components: Components that render often and rely solely on the input props to determine their rendering output and have no internal state or side effects.

If none of the above scenarios are true, React memo will have negligible benefits and may add unnecessary complexity to your application. To take one of the examples above, if you use React memo on a component that usually renders with different props, React will do two jobs; it will invoke the comparison function to determine whether the previous and next props are equal, and because the props comparison will always return false in this scenario, React will re-render the component anyway. So, you will get no performance benefits, and this will actually result in more overhead than benefit.

You should use the profiler tool provided by React to identify any performance issues. The Profiler tool allows you to measure how often a component renders and how long these renders take, helping you determine if memoization would provide actual performance improvements. By profiling first, you can make informed decisions about when React memo is truly beneficial, avoiding needless optimizations.

React provides a couple of other related performance optimization tools. While React memo focuses on optimizing whole component re-renders, these two are a little more granular as they require you to optimize specific parts of your components:

useMemo(): In React, useMemo is a hook that can wrap computationally heavy functions to memoize the result, so if the function is called again with the same arguments, the result doesn't need to be recalculated each time.

useCallback(): This hook can be used to wrap a function to memoize its reference. It takes a set of dependencies that determine whether the function should be redefined; if the dependencies remain the same, the memoized function can be reused. It's used to prevent unnecessary re-creation of functions that are passed down as props.

Performance matters in React applications
According to the Doherty threshold, applications that respond in 400 ms or under keep a user's attention and increase engagement, and anything over that causes frustration and may result in users leaving your application altogether.

As your React application scales and grows in complexity, you may find that it starts to slow down as you add more functionality and complex components. This is why it is advisable to employ optimization strategies such as memoization with React memo, pagination, or lazy loading from the beginning of your project, so that it always performs as well as possible.