在微前端架构中,主应用与子应用之间的通信和状态共享是一个关键问题。我们可以使用多种方法来实现这些功能,包括全局状态管理、自定义事件、和基于发布-订阅的消息机制。
全局状态管理
使用全局状态管理库(如Redux Toolkit)是实现主应用与子应用之间通信的常用方法。主应用和子应用可以共享一个Redux store,通过actions和reducers进行状态更新和数据传递。
- 在主应用中配置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>
);
- 在子应用中使用共享状态
子应用可以通过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机制,主应用向子应用派发事件,子应用监听事件并作出响应。
-
在主应用中派发事件
// 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 );
-
在子应用中监听事件
// 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)来实现主应用与子应用之间的解耦通信。
-
安装PubSubJS
npm install pubsub-js
-
在主应用中发布消息
// src/App.tsx import PubSub from 'pubsub-js';
const publishMessage = () => { PubSub.publish('TOPIC', { message: 'Hello from main app' }); };
return ( Send Message to Sub App );
-
在子应用中订阅消息
// 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;
总结
在本节中,我们探讨了多种实现主应用与子应用之间通信和状态共享的方法,包括全局状态管理、自定义事件和发布-订阅机制。选择合适的通信方式取决于项目的具体需求和复杂度。接下来,我们将继续深入探讨样式隔离与共享的最佳实践。