React状态保留新方案:Activity组件实战指南

更新日期: 2025-11-20 阅读: 48 标签: 状态

在开发中后台系统时,我们经常遇到这样的需求:用户在一个复杂的筛选面板中填写了很多条件,切换到其他页面后再回来,希望之前填写的内容还在。

面对这个问题,开发人员通常尝试几种方案:

  1. 用Redux全局存储状态 → 代码变得复杂,维护困难

  2. css隐藏组件 → 组件仍在运行,影响性能

  3. 自己实现状态缓存 → 边界情况太多,处理起来很麻烦

现在好消息来了,react 19.2引入了Activity组件,专门解决这个问题。


传统方案的问题

方案1:条件渲染

function App() {
  const [show, setShow] = useState(true);
  
  return (
    <>
      {show && <FilterPanel />}
    </>
  );
}

这种方式的问题:组件完全卸载,所有状态都会丢失。

方案2:CSS隐藏

function App() {
  const [show, setShow] = useState(true);
  
  return (
    <div style={{ display: show ? 'block' : 'none' }}>
      <FilterPanel />
    </div>
  );
}

这种方式的问题:组件虽然看不见了,但仍在运行,useEffect还会执行,可能造成资源浪费。

方案3:手动状态管理

function TabContainer() {
  const [cache, setCache] = useState({});
  
  const handleTabChange = (tab) => {
    // 保存当前状态
    const currentData = getFormData();
    setCache(prev => ({
      ...prev,
      [currentTab]: currentData
    }));
    setCurrentTab(tab);
  };
  
  // 还要处理状态恢复、滚动位置等...
}

这种方式代码量大,容易出错。


Activity组件的基本用法

React 19.2的Activity组件提供了优雅的解决方案:

import { Activity } from 'react';

function App() {
  const [isVisible, setIsVisible] = useState(true);
  
  return (
    <Activity mode={isVisible ? 'visible' : 'hidden'}>
      <FilterPanel />
    </Activity>
  );
}


Activity组件的工作原理

当mode设置为'hidden'时:

  • 组件在dom中保留(状态不会丢失)

  • 但会应用display: none样式

  • useEffect的清理函数会执行

  • 组件进入低优先级渲染

当mode设置为'visible'时:

  • 移除display: none样式

  • 重新执行useEffect

  • 组件恢复正常渲染


实际应用场景

场景1:Tab切换

function TabSystem() {
  const [activeTab, setActiveTab] = useState('list');
  
  return (
    <div>
      <nav>
        <button onClick={() => setActiveTab('list')}>列表</button>
        <button onClick={() => setActiveTab('form')}>表单</button>
      </nav>
      
      <Activity mode={activeTab === 'list' ? 'visible' : 'hidden'}>
        <ProductList />
      </Activity>
      
      <Activity mode={activeTab === 'form' ? 'visible' : 'hidden'}>
        <ProductForm />
      </Activity>
    </div>
  );
}

这样切换Tab时,每个Tab的状态都会保留。

场景2:侧边栏筛选

function DataPage() {
  const [sidebarOpen, setSidebarOpen] = useState(true);
  
  return (
    <div className="page">
      <button onClick={() => setSidebarOpen(!sidebarOpen)}>
        {sidebarOpen ? '收起' : '展开'}筛选
      </button>
      
      <Activity mode={sidebarOpen ? 'visible' : 'hidden'}>
        <SidebarFilters />
      </Activity>
      
      <MainContent />
    </div>
  );
}

function SidebarFilters() {
  const [filters, setFilters] = useState({
    category: '',
    priceRange: [0, 1000],
    keywords: ''
  });
  
  // 这些状态在侧边栏收起/展开时都会保留
  return (
    <div className="sidebar">
      <input 
        value={filters.keywords}
        onChange={(e) => setFilters({...filters, keywords: e.target.value})}
        placeholder="搜索关键词"
      />
      {/* 更多筛选条件 */}
    </div>
  );
}

场景3:Modal对话框

function UserPage() {
  const [modalOpen, setModalOpen] = useState(false);
  
  return (
    <div>
      <button onClick={() => setModalOpen(true)}>
        编辑用户信息
      </button>
      
      <Activity mode={modalOpen ? 'visible' : 'hidden'}>
        <Modal onClose={() => setModalOpen(false)}>
          <UserForm />
        </Modal>
      </Activity>
    </div>
  );
}

function UserForm() {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    role: ''
  });
  
  // 即使用户关闭Modal,表单数据也会保留
  // 下次打开时可以直接继续编辑
  
  return (
    <form>
      <input 
        value={formData.name}
        onChange={(e) => setFormData({...formData, name: e.target.value})}
      />
      {/* 其他表单字段 */}
    </form>
  );
}


资源管理

Activity组件的一个重要特性是能正确管理资源:

function DataMonitor({ deviceId }) {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    console.log('开始获取数据');
    
    // 建立WebSocket连接
    const ws = new WebSocket(`ws://api.example.com/devices/${deviceId}`);
    
    ws.onmessage = (event) => {
      setData(JSON.parse(event.data));
    };
    
    // 定时发送心跳
    const heartbeat = setInterval(() => {
      ws.send('ping');
    }, 5000);
    
    return () => {
      console.log('清理资源');
      clearInterval(heartbeat);
      ws.close();
    };
  }, [deviceId]);
  
  return <div>{/* 显示数据 */}</div>;
}

当Activity的mode变为'hidden'时,useEffect的清理函数会自动执行,关闭WebSocket连接和定时器。


性能考虑

Activity组件虽然好用,但也要注意合理使用:

适合的场景:

  • Tab切换系统

  • 侧边栏、抽屉组件

  • Modal对话框

  • 需要保留状态的复杂表单

不适合的场景:

  • 组件渲染特别慢(超过500ms)

  • 内存受限的移动端应用

  • 很少切换的页面


使用建议

  1. 对于频繁切换的组件,使用Activity可以提升用户体验

  2. 对于很少使用的功能,直接用条件渲染即可

  3. 注意内存使用,不要同时渲染太多hidden组件


与其他方案对比

方案状态保留资源清理使用难度
条件渲染❌ 不保留✅ 会清理简单
CSS隐藏✅ 保留❌ 不清理简单
手动管理✅ 保留⚠️ 需手动复杂
Activity✅ 保留✅ 自动清理简单

总结

React 19.2的Activity组件解决了前端开发中的一个常见痛点。它既保留了组件状态,又能正确管理资源,使用起来还很简单。

在实际项目中,你可以这样选择:

  • 需要保留状态且频繁切换的组件 → 使用Activity

  • 简单组件或很少切换的组件 → 使用条件渲染

  • 特殊需求场景 → 考虑手动状态管理

Activity组件让React开发更加顺手,特别是在处理复杂交互场景时,能显著提升开发效率和用户体验。

本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!

链接: https://fly63.com/article/detial/13204

Javascript 状态管理工具 DataSet ,实现数据的订阅、查询、撤销和恢复

网页是用户与网站对接的入口,当我们允许用户在网页上进行一些频繁的操作时,对用户而言,误删、误操作是一件令人抓狂的事情,“如果时光可以倒流,这一切可以重来……”。

理解 React 轻量状态管理库 Unstated

在React写应用的时候,难免遇到跨组件通信的问题。现在已经有很多的解决方案。React本身的Context,Redux结合React-redux,Mobx结合mobx-react

你再也不用使用 Redux、Mobx、Flux 等状态管理了

这个库的作者希望使用 React 内置 API ,直接实现状态管理的功能。看完这个库的说明后,没有想到代码可以这个玩。短短几行代码,仅仅使用 React Hooks ,就实现了状态管理的功能。

为什么要使用状态管理

我们平时开发的大部分项目,由于复杂度不够, 很少使用 Vuex、Redux 等状态管理库,就算引入了 Vuex 这些库,也只是当作一个全局数据引用,并非对应用状态进行管理。但一旦页面的复杂度比较高,必然要引入状态管理,今天就聊聊我理解中的状态管理。

React使用Hooks与Context替代Redux状态管理

React Hooks 在 2018 年年底就已经公布了,正式发布是在 2019 年 5 月,关于它到底能做什么用,并不在本文的探讨范围之内,本文旨在摸索,如何基于 Hooks 以及 Context,实现多组件的状态共享,完成一个精简版的 Redux。

如何使用react hooks来进行状态管理?

首先要明确为什么要使用redux,这一点很重要,如果不知道为什么使用redux,那么在开发的过程中肯定不能合理的使用redux.首先来看redux的本质:redux做为一款状态管理工具,主要是为了解决组件间通信的问题。

Flutter基础--状态管理

当我们使用编译器创建一个新Flutter应用的时候,我们可以在主界面看到两个小部件StatelessWidget和StatefulWidget。这是两个最常见使用最频繁的小部件了。StatelessWidget ,StatefulWidget

共享可变状态中出现的问题以及如何避免?

本文回答了以下问题:么是共享可变状态?为什么会出现问题?如何避免其问题?标有(高级)的部分会更深入,如果你想更快地阅读本文,可以跳过。

使用Observable实现Vue全局状态共享

项目不大, 又不想用Vuex, 那么使用Observable来实现状态共享也不失为一个选择。用法 :让一个对象可响应。Vue 内部会用它来处理 data 函数返回的对象

node如何实现保持登录状态?

当我们登录成功,在这个页面刷新,页面并没有保存登录状态;今天我们就来看一下如何在后台使用cookie保存用户登录状态。做到刷新页面仍然显示在用户登录界面。node实现保持登录状态的方法如下:

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!