0Pricing
React Academy · レッスン

MFE間の共有StateとRouting

micro-frontends間でglobal event busまたはcontextを共有し、client-side routingを連携させます。

「MFE間の共有StateとRouting」はCoddyKit上の無料React Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。

状態共有の課題

別々のバンドルに含まれるマイクロフロントエンド同士は、Reactの状態やコンテキストを直接共有できません。そのため、カスタムイベント、共有ストア、URL、pub/subイベントバスなどの代替戦略が必要です。

ブラウザーのカスタムイベント

ブラウザーのCustomEvent APIをシンプルなイベントバスとして使用すると、マイクロフロントエンド同士を結合せずに通信できます。

// Remote emits:
window.dispatchEvent(new CustomEvent('cart:add', { detail: { productId: '123' } }));

// Host listens:
useEffect(() => {
  const handler = (e: CustomEvent) => addToCart(e.detail.productId);
  window.addEventListener('cart:add', handler);
  return () => window.removeEventListener('cart:add', handler);
}, []);

共有イベントバスライブラリ

共有された小さなpub/subライブラリ(Module FederationまたはURLで読み込むシングルトンを介して共有します)により、すべてのMFEから利用できる型付きイベントバスを提供できます。

// Singleton event bus
const bus = {
  listeners: new Map<string, Function[]>(),
  emit(event: string, data: unknown) {
    this.listeners.get(event)?.forEach(fn => fn(data));
  },
  on(event: string, fn: Function) {
    if (!this.listeners.has(event)) this.listeners.set(event, []);
    this.listeners.get(event)!.push(fn);
    return () => this.off(event, fn);
  },
  off(event: string, fn: Function) {
    const list = this.listeners.get(event) || [];
    this.listeners.set(event, list.filter(f => f !== fn));
  },
};
export default bus;

共有状態としてのURL

URL(パスとクエリパラメーター)は、すべてのMFEで自然に共有されます。選択中の項目、アクティブなタブ、フィルター値などのナビゲーション状態に使用してください。

// Remote reads from URL:
const params = new URLSearchParams(window.location.search);
const productId = params.get('product');

// Remote navigates via history API (or exposes a navigate callback from host):
window.history.pushState({}, '', '/products?product=456');

ルーティングアーキテクチャ

通常、シェル/ホストアプリがトップレベルのルーターを所有します。リモートのマイクロフロントエンドには、現在のパスとnavigateコールバックをpropsとして渡します。

// Host passes routing control to remote:
<RemoteProductsApp
  basepath="/products"
  navigate={(path) => router.push(path)}
/>

// Remote uses basepath for its internal router:
<BrowserRouter basename={basepath}>
  <Routes>...</Routes>
</BrowserRouter>

Module FederationとReact Router

各MFEは、ベースパスの範囲内で独自のReact Routerを実行できます。ホストのルーターがトップレベルのナビゲーションを処理し、各リモートがサブナビゲーションを独立して処理します。

// Remote App component:
export function ProductsApp({ basepath = '/products' }) {
  return (
    <BrowserRouter basename={basepath}>
      <Routes>
        <Route path="/" element={<ProductList />} />
        <Route path="/:id" element={<ProductDetail />} />
      </Routes>
    </BrowserRouter>
  );
}

共有認証状態

認証状態(ユーザー、トークン)は通常、シェルが所有し、propsとしてリモートに渡すか、共有シングルトンストアを介して公開します。

// Host provides auth via props:
<RemoteCheckout
  userId={currentUser.id}
  token={accessToken}
  onLogout={handleLogout}
/>

共有ストアとしてのZustand

Module Federationを介してZustandストアをシングルトンとして共有すると、すべてのMFEがメモリ上の同じストアインスタンスから読み取ります。

// shared/store.ts (exposed as singleton)
import { create } from 'zustand';
export const useCartStore = create(set => ({
  items: [],
  addItem: (item) => set(state => ({ items: [...state.items, item] })),
}));

// Configured as singleton in MF shared config

MFE間通信のアンチパターン

深くネストされたコールバックチェーン、内部コンポーネント状態の共有、別のMFEの内部APIへの密結合は避けてください。通信は粗粒度のイベントと公開されたコントラクトに限定します。

MFE間のインタラクションのテスト

イベント名やデータ形式などのイベントコントラクトを、UIとは分けてテストします。コントラクトテストを使って、プロデューサーとコンシューマーがイベントスキーマに合意していることを確認してください。

クイックチェック

複数のマイクロフロントエンド間で、結合せずにナビゲーションやフィルターの状態を共有する最も簡単な方法は何ですか?

まとめ

MFE間では、カスタムイベント、シングルトンイベントバス、URL、共有ストア(Zustand/シングルトン)を使って状態を共有します。シェルがトップレベルのルーターを所有し、ベースパスとnavigateをリモートに渡します。MFE間のコントラクトは粗粒度に保ち、適切な型を付けてください。

よくある質問

「MFE間の共有StateとRouting」レッスンは無料ですか?

はい。「MFE間の共有StateとRouting」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。

「MFE間の共有StateとRouting」で何を学びますか?

micro-frontends間でglobal event busまたはcontextを共有し、client-side routingを連携させます。 ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

React Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「MFE間の共有StateとRouting」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このReact Academyレッスンでコードを書いて実行できますか?

はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Micro-Frontendの概念とトレードオフ
  2. Webpack 5によるModule Federation
  3. MFE間の共有StateとRouting
  4. MFEの独立デプロイとCI Pipeline
← React Academyに戻る