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

推荐订阅源

博客园 - 叶小钗
Martin Fowler
Martin Fowler
H
Help Net Security
月光博客
月光博客
Stack Overflow Blog
Stack Overflow Blog
V
Visual Studio Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
K
Kaspersky official blog
MongoDB | Blog
MongoDB | Blog
L
LINUX DO - 最新话题
S
Schneier on Security
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cyber Attacks, Cyber Crime and Cyber Security
AI
AI
The Hacker News
The Hacker News
Latest news
Latest news
D
Darknet – Hacking Tools, Hacker News & Cyber Security
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
GbyAI
GbyAI
SecWiki News
SecWiki News
C
Check Point Blog
T
The Exploit Database - CXSecurity.com
J
Java Code Geeks
V2EX - 技术
V2EX - 技术
Y
Y Combinator Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
U
Unit 42
Attack and Defense Labs
Attack and Defense Labs
Security Latest
Security Latest
Help Net Security
Help Net Security
博客园 - Franky
L
LINUX DO - 热门话题
N
News and Events Feed by Topic
Cloudbric
Cloudbric
P
Proofpoint News Feed
Hacker News - Newest:
Hacker News - Newest: "LLM"
博客园 - 【当耐特】
Schneier on Security
Schneier on Security
Google Online Security Blog
Google Online Security Blog
C
Cisco Blogs
Webroot Blog
Webroot Blog
C
CERT Recently Published Vulnerability Notes
Simon Willison's Weblog
Simon Willison's Weblog
A
Arctic Wolf
O
OpenAI News
T
Threat Research - Cisco Blogs
Know Your Adversary
Know Your Adversary
C
CXSECURITY Database RSS Feed - CXSecurity.com
The Last Watchdog
The Last Watchdog

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
React 19.2 Activity Component: Keeping Unmounted Trees Alive for Faster Tab Switching
jsmanifest · 2026-06-20 · via DEV Community

React 19.2 Activity Component: Keeping Unmounted Trees Alive for Faster Tab Switching

The Tab Switching Problem Every React Developer Faces

Most state persistence problems in React stem from the framework's unmount behavior. When developers build tab systems, multi-step forms, or dashboard layouts, they typically use conditional rendering. The active tab renders, the inactive tabs unmount completely. Users switch back to a previous tab and discover their form data vanished, their video player reset to 0:00, or their carefully filtered table reverted to defaults.

Teams work around this with external state managers, CSS display: none tricks, or lifting state into parent components. These patterns work but introduce overhead. React 19.2's Activity component solves this at the framework level by preserving the component tree and state while the component is inactive. The tree stays mounted but paused—no re-renders, no effect cleanup, no data loss.

This distinction is critical. Activity doesn't hide components with CSS. It keeps the fiber tree alive in React's reconciler but skips work until the component becomes active again. The performance characteristics differ significantly from both conditional rendering and visibility toggling.

What Is the Activity Component and How Does It Work?

The Activity component wraps child components and controls their lifecycle based on a boolean mode prop. When mode="visible", the children render and behave normally—effects run, updates process, event handlers fire. When mode="hidden", React keeps the component tree mounted but pauses all work.

import { Activity } from 'react';

function TabPanel({ isActive, children }) {
  return (
    <Activity mode={isActive ? 'visible' : 'hidden'}>
      {children}
    </Activity>
  );
}

The paused state differs from display: none in three ways. First, React stops processing updates entirely—state changes queue but don't trigger re-renders. Second, effects don't clean up when transitioning to hidden mode. useEffect cleanup functions only run when the component actually unmounts, not when Activity hides it. Third, the component tree remains in the reconciler, so switching back to visible mode is instantaneous.

This matters because the pause-resume pattern eliminates the entire category of bugs where components lose internal state on tab switches. Video players remember playback position, forms retain validation state, and tables preserve filter selections—all without lifting state or adding external dependencies.

Building Your First Tab System With Activity

The simplest Activity implementation handles tab switching in a settings panel or wizard interface. The pattern requires three elements: tab buttons, content components wrapped in Activity, and local state to track the active tab.

import { Activity } from 'react';
import { useState } from 'react';

function SettingsPanel() {
  const [activeTab, setActiveTab] = useState('profile');

  return (
    <div>
      <nav>
        <button onClick={() => setActiveTab('profile')}>
          Profile
        </button>
        <button onClick={() => setActiveTab('notifications')}>
          Notifications
        </button>
        <button onClick={() => setActiveTab('security')}>
          Security
        </button>
      </nav>

      <Activity mode={activeTab === 'profile' ? 'visible' : 'hidden'}>
        <ProfileSettings />
      </Activity>

      <Activity mode={activeTab === 'notifications' ? 'visible' : 'hidden'}>
        <NotificationSettings />
      </Activity>

      <Activity mode={activeTab === 'security' ? 'visible' : 'hidden'}>
        <SecuritySettings />
      </Activity>
    </div>
  );
}

function ProfileSettings() {
  const [name, setName] = useState('');

  // This state persists when tab switches away
  return (
    <form>
      <input
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="Display name"
      />
    </form>
  );
}

Activity component tab switching demonstration

Activity component tab switching demonstration

Each tab component manages its own state. When users switch from Profile to Notifications, ProfileSettings enters hidden mode but retains the name state value. Switch back and the input field shows exactly what the user typed before. No form library required, no parent state hoisting, no context providers.

The failure mode here is subtle but expensive. Without Activity, developers typically solve this by lifting state into SettingsPanel and passing it down as props. That works until the tab components grow complex with nested forms, validation logic, and side effects. The parent becomes a massive state orchestrator, and prop drilling turns into a maintenance nightmare.

Activity vs Display None vs Conditional Rendering: A Performance Comparison

Teams reach for three patterns when building tab systems: conditional rendering, CSS visibility, and now Activity. The tradeoffs matter for production applications handling complex UIs.

Conditional rendering delivers the smallest bundle size and lowest memory footprint. The inactive tab doesn't exist in the DOM or React tree. This works perfectly for simple content that doesn't maintain state—static text, read-only displays, or components that fetch fresh data on every mount. The cost appears when users switch tabs frequently. Each activation triggers a full component lifecycle: constructor, effects, async data fetching, derived state calculations. For a video player or data table, that overhead compounds quickly.

CSS display: none solves the state problem by keeping all tabs mounted but hidden. React continues processing updates for invisible components. If a hidden tab contains a live feed or auto-updating chart, those updates still trigger re-renders even though users can't see them. The memory overhead grows with the number of tabs, and performance degrades when multiple hidden tabs run expensive operations simultaneously.

Activity combines the benefits of both patterns. Components mount once and preserve state like CSS visibility, but React skips work for hidden tabs like conditional rendering. The implementation pauses the fiber tree instead of removing it, so memory usage stays closer to CSS visibility than conditional rendering. The key advantage emerges in applications with dozens of tabs or deeply nested component trees—switching tabs becomes instant because React doesn't rebuild the tree.

In other words, Activity optimizes for user experience over raw technical metrics. The memory footprint exceeds conditional rendering but the perceived performance wins. Users notice when a tab takes 200ms to remount. They don't notice an extra 50KB of retained state.

Real-World Use Cases: Forms, Video Players, and Dashboards

The practical applications for Activity cluster around three categories: complex forms with validation, media players with playback state, and data-heavy dashboards with filters.

Multi-step forms demonstrate the pattern's value immediately. Consider an onboarding wizard with five steps, each containing multiple fields and async validation. Without Activity, developers either lift all form state to the wizard component (creating a massive state object) or accept that users lose progress when clicking "back" to review earlier steps. Activity eliminates both problems. Each step component manages its own form state, validation runs once per step, and users can navigate freely without data loss.

Form state preservation with Activity component

Form state preservation with Activity component

Video players and audio interfaces need Activity for playback position and quality settings. When users switch tabs in a video tutorial application, the player component enters hidden mode but retains the current timestamp, playback speed, and subtitle preferences. The video element itself can stay in the DOM but paused, avoiding the expensive re-initialization that happens with conditional rendering. This pattern extends to any media-heavy application—podcast players, image galleries with zoom state, or audio workstations with timeline positions.

Dashboard applications with heavy data transformations benefit from Activity's deferred updates. A financial dashboard might show ten different chart views, each processing the same dataset with different aggregations. Without Activity, hiding a chart with CSS means React still processes updates when the underlying data changes. With Activity, those hidden charts skip re-renders entirely until users switch back to them. The data stays cached in component state, the charts remain mounted, but computation only happens when visible.

The implication here is that Activity shifts the optimization strategy. Instead of memoizing expensive computations or debouncing updates across all tabs, developers can let hidden tabs stay idle. The complexity reduction matters as much as the performance gain.

How Activity Pauses Effects and Defers Updates

The mechanism behind Activity's pause behavior differs from simple conditional logic. React tracks each fiber's activity state and skips reconciliation work for hidden subtrees. Effects behave differently than they do with unmounting.

When a component transitions from visible to hidden, React does not call effect cleanup functions. Consider a component with a WebSocket connection managed by useEffect. In normal unmounting, the cleanup function closes the socket. With Activity's hidden mode, the cleanup doesn't run. The socket stays open, the subscription remains active, but React stops processing incoming messages until the component becomes visible again.

This behavior requires careful handling for resources that consume bandwidth or processing power even when inactive. A component that subscribes to a real-time data feed should probably pause the subscription manually when entering hidden mode, rather than relying on Activity alone:

function LiveFeed() {
  const [data, setData] = useState([]);
  const [isActive, setIsActive] = useState(true);

  useEffect(() => {
    if (!isActive) return;

    const subscription = dataSource.subscribe(setData);
    return () => subscription.unsubscribe();
  }, [isActive]);

  return <Activity mode={isActive ? 'visible' : 'hidden'}>
    <FeedDisplay data={data} />
  </Activity>;
}

State updates queued while a component is hidden batch together and process when the component becomes visible. This prevents wasted re-renders but can create a perception lag if many updates accumulate. For most UIs this batching improves performance. For components that must stay synchronized with external state even when hidden—like a chat application that shows unread counts—developers need additional patterns. Activity works best when hidden components can legitimately pause their work.

The distinction between Activity's pause and traditional unmount cleanup matters for debugging. Effect cleanup bugs often manifest as memory leaks or stale subscriptions. With Activity, those bugs might stay hidden longer because cleanup never runs until actual unmount. Teams adopting Activity need to audit effects that assume cleanup runs on every deactivation.

Production Patterns: When NOT to Use Activity

Activity solves specific problems exceptionally well, but several scenarios call for different approaches. The pattern breaks down when components must stay synchronized with rapidly changing external state, when memory constraints dominate performance concerns, or when SEO requires server-rendered content for all tabs.

Real-time dashboards with critical alerts demonstrate the first limitation. A monitoring dashboard showing server health across multiple tabs needs to process updates even when users view a different tab. If the CPU usage tab is hidden but a server starts failing, the notification must appear immediately. Activity would defer those updates until the user switches back. In other words, when hidden state changes have observable side effects that users need, conditional rendering with external state management like Jotai or TanStack Query becomes the better choice.

Mobile applications and memory-constrained environments expose Activity's overhead. Each hidden component tree consumes memory proportional to its complexity. An application with 20 tabs, each containing large data tables or image galleries, might exhaust available memory if all tabs stay mounted. Conditional rendering with code splitting delivers better memory characteristics in these scenarios. Load tab components on demand, let them unmount when inactive, and accept the re-initialization cost as a tradeoff for lower baseline memory usage.

SEO requirements conflict with Activity's client-side nature. Search engines need content in the initial HTML payload. A marketing site with tabbed product details should server-render all tabs and use CSS visibility for client-side switching. Activity adds no value here because the content must exist in the DOM regardless of user interaction.

The failure mode here is subtle but expensive. Teams that adopt Activity everywhere create applications that feel fast on modern devices but struggle on lower-end hardware or complex UIs. The pattern works best when applied selectively to components where state preservation meaningfully improves user experience—complex forms, media players, filtered data views. Not every tab system needs it.

Conclusion: Activity Component Changes the Game for State Persistence

React 19.2's Activity component eliminates an entire category of state management complexity. The pattern preserves component state across tab switches without CSS hacks, external state libraries, or prop drilling. For forms, media players, and data-heavy dashboards, Activity delivers instant tab switching and eliminates the data loss bugs that plague conditional rendering.

The key insight is that Activity optimizes for perceived performance over technical metrics. The memory footprint exceeds conditional rendering, but users experience tabs as instant because the component tree stays mounted. This tradeoff works for most web applications where user experience trumps marginal memory savings.

Production adoption requires understanding the pattern's boundaries. Activity excels when components can legitimately pause work while hidden. It struggles when hidden components must stay synchronized with real-time data or when memory constraints dominate. The implementation is straightforward—wrap content in <Activity mode={...}> and let React handle the pause-resume lifecycle.

That covers the essential patterns for React 19.2's Activity component. Apply these in production and the difference will be immediate. Avoid the common mistakes in 10 things not to do when building React apps, combine Activity with proper state management, and tab systems become a solved problem.