You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在single-spa中使用RxJs共享UI状态?求React场景示例

React + single-spa + RxJS 状态共享完整示例

我刚好在React + single-spa的项目里实践过用RxJS做跨应用状态共享,给你整理了一个覆盖所有场景的基础示例,核心思路是用全局可导入的RxJS状态服务,借助BehaviorSubject(它能保存当前状态值,新订阅者也能拿到最新状态)实现双向/多向的状态同步。

1. 创建共享状态服务

先新建一个shared-state.js(这个文件要放在所有应用都能访问到的位置,比如作为single-spa的共享模块,或者打包成独立UMD包供全局导入):

import { BehaviorSubject } from 'rxjs';

// 定义独立的状态流,按业务域拆分更清晰
const userSubject = new BehaviorSubject(null);
const themeSubject = new BehaviorSubject('light');

// 暴露状态操作API
export const sharedState = {
  // 用户信息状态操作
  setUser: (user) => userSubject.next(user),
  getUser: () => userSubject.getValue(),
  subscribeToUser: (callback) => userSubject.subscribe(callback),
  
  // 主题状态操作
  setTheme: (theme) => themeSubject.next(theme),
  getTheme: () => themeSubject.getValue(),
  subscribeToTheme: (callback) => themeSubject.subscribe(callback),
  
  // 通用订阅清理方法,方便React组件卸载时清理
  unsubscribe: (subscription) => subscription.unsubscribe()
};

2. 根应用 → 微应用 共享状态

根应用更新状态

比如根应用导航栏的主题切换按钮,点击时更新共享状态:

// 根应用 Navbar 组件
import { sharedState } from './shared-state';

function Navbar() {
  const toggleTheme = () => {
    const currentTheme = sharedState.getTheme();
    sharedState.setTheme(currentTheme === 'light' ? 'dark' : 'light');
  };

  return (
    <nav className="navbar">
      <button onClick={toggleTheme}>切换主题</button>
    </nav>
  );
}

微应用订阅状态

微应用的任意组件可以订阅主题状态,实时同步UI:

// 微应用 Profile 组件
import { useEffect, useState } from 'react';
import { sharedState } from '../shared-state'; // 按实际路径导入

function Profile() {
  // 初始化时拿到当前状态
  const [theme, setTheme] = useState(sharedState.getTheme());

  useEffect(() => {
    // 订阅主题变化,更新本地状态
    const subscription = sharedState.subscribeToTheme((newTheme) => {
      setTheme(newTheme);
    });

    // 组件卸载时清理订阅,避免内存泄漏
    return () => sharedState.unsubscribe(subscription);
  }, []);

  return (
    <div style={{ 
      background: theme === 'light' ? '#fff' : '#333',
      color: theme === 'light' ? '#000' : '#fff',
      padding: '1rem'
    }}>
      <h2>用户资料页</h2>
      <p>当前主题:{theme}</p>
    </div>
  );
}

3. 微应用 → 根应用 共享状态

微应用更新状态

比如微应用的登录表单,登录成功后更新共享的用户信息:

// 微应用 Login 组件
import { useState } from 'react';
import { sharedState } from '../shared-state';

function Login() {
  const [username, setUsername] = useState('');

  const handleLogin = () => {
    // 模拟登录接口返回的用户信息
    const userInfo = { id: 1001, name: username, avatar: 'default-avatar.png' };
    sharedState.setUser(userInfo);
  };

  return (
    <div className="login-form">
      <input 
        type="text" 
        value={username} 
        onChange={(e) => setUsername(e.target.value)} 
        placeholder="输入用户名"
      />
      <button onClick={handleLogin}>登录</button>
    </div>
  );
}

根应用订阅状态

根应用导航栏订阅用户状态,动态显示登录信息:

// 根应用 Navbar 组件
import { useEffect, useState } from 'react';
import { sharedState } from './shared-state';

function Navbar() {
  const [user, setUser] = useState(sharedState.getUser());

  useEffect(() => {
    const subscription = sharedState.subscribeToUser((newUser) => {
      setUser(newUser);
    });

    return () => sharedState.unsubscribe(subscription);
  }, []);

  return (
    <nav className="navbar">
      {user ? (
        <span className="user-info">欢迎回来,{user.name}</span>
      ) : (
        <span className="unlogin">未登录</span>
      )}
      <button onClick={toggleTheme}>切换主题</button>
    </nav>
  );
}

4. 微应用之间 共享状态

逻辑和上面一致,比如微应用A修改用户信息,微应用B实时同步:

微应用A(订单应用)更新状态

// 微应用A UserSettings 组件
import { sharedState } from '../shared-state';

function UserSettings() {
  const updateUserName = () => {
    const currentUser = sharedState.getUser();
    // 更新用户名,保留其他字段
    sharedState.setUser({ ...currentUser, name: '新昵称' });
  };

  return (
    <button onClick={updateUserName}>修改昵称</button>
  );
}

微应用B(消息应用)订阅状态

// 微应用B MessageCenter 组件
import { useEffect, useState } from 'react';
import { sharedState } from '../shared-state';

function MessageCenter() {
  const [user, setUser] = useState(sharedState.getUser());

  useEffect(() => {
    const subscription = sharedState.subscribeToUser((newUser) => {
      setUser(newUser);
    });

    return () => sharedState.unsubscribe(subscription);
  }, []);

  return (
    <div className="message-center">
      <p>您好,{user?.name},您有3条未读消息</p>
    </div>
  );
}

关键注意事项

  • 确保所有应用能正确导入shared-state.js:如果用single-spa的模块联邦,要配置好依赖共享;如果全局导入,要保证该文件在所有应用加载前完成加载。
  • React组件中订阅时,一定要在useEffect的清理函数里取消订阅,避免内存泄漏。
  • 复杂场景下建议拆分多个BehaviorSubject,每个对应一个独立业务域,避免状态混乱。

内容的提问来源于stack exchange,提问作者Saswata Arabinda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 14:07:35