微前端 - qiankun 入门到实践——第七节:通信与共享状态

929 阅读3分钟

在微前端架构中,主应用与子应用之间的通信和状态共享是一个关键问题。我们可以使用多种方法来实现这些功能,包括全局状态管理、自定义事件、和基于发布-订阅的消息机制。

全局状态管理

使用全局状态管理库(如Redux Toolkit)是实现主应用与子应用之间通信的常用方法。主应用和子应用可以共享一个Redux store,通过actions和reducers进行状态更新和数据传递。

  1. 在主应用中配置Redux

首先,在主应用中配置Redux store:

// src/store.ts
import { configureStore } from '@reduxjs/toolkit';
import userReducer from './slices/userSlice';

export const store = configureStore({
  reducer: {
    user: userReducer,
  },
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

src/main.tsx中,将Redux Provider包裹在Router外层:

// src/main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import { Provider } from 'react-redux';
import App from './App';
import { store } from './store';
import './index.css';

const container = document.getElementById('root');
const root = ReactDOM.createRoot(container!);

root.render(
  <React.StrictMode>
    <Provider store={store}>
      <Router>
        <Routes>
          <Route path="/*" element={<App />} />
        </Routes>
      </Router>
    </Provider>
  </React.StrictMode>
);
  1. 在子应用中使用共享状态

子应用可以通过props将主应用的Redux store传递进来,并在需要的地方使用:

// src/main.tsx(子应用)
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { Provider } from 'react-redux';
import { store } from './store';

function render(props: any) {
  const { container } = props;
  const root = ReactDOM.createRoot(container ? container.querySelector('#root') : document.querySelector('#root'));
  root.render(
    <React.StrictMode>
      <Provider store={props.store || store}>
        <App />
      </Provider>
    </React.StrictMode>
  );
}

if (!window.__POWERED_BY_QIANKUN__) {
  render({});
}

export async function bootstrap() {
  console.log('React app bootstraped');
}

export async function mount(props: any) {
  render(props);
}

export async function unmount(props: any) {
  const { container } = props;
  const root = container ? container.querySelector('#root') : document.querySelector('#root');
  ReactDOM.unmountComponentAtNode(root);
}

通过这种方式,子应用可以与主应用共享Redux store,从而实现状态管理和数据同步。

自定义事件

使用自定义事件也是主应用与子应用之间通信的有效方法。可以通过JavaScript的Event机制,主应用向子应用派发事件,子应用监听事件并作出响应。

  1. 在主应用中派发事件

    // src/App.tsx const dispatchEventToSubApp = (event: string, detail: any) => { const customEvent = new CustomEvent(event, { detail }); window.dispatchEvent(customEvent); };

    const handleButtonClick = () => { dispatchEventToSubApp('custom-event', { message: 'Hello from main app' }); };

    return ( Send Message to Sub App );

  2. 在子应用中监听事件

    // src/App.tsx(子应用) import React, { useEffect } from 'react';

    const App = () => { useEffect(() => { const handleCustomEvent = (event: CustomEvent) => { console.log('Received message from main app:', event.detail.message); };

    window.addEventListener('custom-event', handleCustomEvent);
    
    return () => {
      window.removeEventListener('custom-event', handleCustomEvent);
    };
    

    }, []);

    return (

    Sub Application

    ); };

    export default App;

基于发布-订阅的消息机制

可以使用轻量级的发布-订阅库(如PubSubJS)来实现主应用与子应用之间的解耦通信。

  1. 安装PubSubJS

    npm install pubsub-js

  2. 在主应用中发布消息

    // src/App.tsx import PubSub from 'pubsub-js';

    const publishMessage = () => { PubSub.publish('TOPIC', { message: 'Hello from main app' }); };

    return ( Send Message to Sub App );

  3. 在子应用中订阅消息

    // src/App.tsx(子应用) import React, { useEffect } from 'react'; import PubSub from 'pubsub-js';

    const App = () => { useEffect(() => { const token = PubSub.subscribe('TOPIC', (msg, data) => { console.log('Received message from main app:', data.message); });

    return () => {
      PubSub.unsubscribe(token);
    };
    

    }, []);

    return (

    Sub Application

    ); };

    export default App;

总结

在本节中,我们探讨了多种实现主应用与子应用之间通信和状态共享的方法,包括全局状态管理、自定义事件和发布-订阅机制。选择合适的通信方式取决于项目的具体需求和复杂度。接下来,我们将继续深入探讨样式隔离与共享的最佳实践。