import { inject, injectable, provide, useDependencies } from '@servicetitan/react-ioc'; import { observer } from 'mobx-react'; import { QueryApiStore } from '../utils/query-api.store'; import type { QueryApiOptions } from '../utils/query.api'; import { Fragment, useState } from 'react'; import { getQueryClient } from '../utils/get-query-client'; interface Job { id: number; title: string; description: string; } @injectable() class JobsApi { async get(): Promise<{ data: Job[] }> { // eslint-disable-next-line no-console console.log('Fetching jobs...'); // Simulate an API call return new Promise(resolve => { setTimeout(() => { resolve({ data: [ { id: 1, title: 'Job 1', description: 'Description 1' }, { id: 2, title: 'Job 2', description: 'Description 2' }, ], }); }, 2000); }); } } @injectable() class JobsStore extends QueryApiStore { @inject(JobsApi) protected api?: JobsApi; get queryOptions(): QueryApiOptions { return { queryKey: ['demo', 'jobs'], queryFn: async () => (await this.api?.get())?.data || [], }; } } const Mfe = provide({ singletons: [getQueryClient('page'), JobsApi, JobsStore], })( observer(() => { const [{ data, isLoading }] = useDependencies(JobsStore); if (isLoading) { return
Loading for 2 seconds...
; } return (

MFE -{' '} {`provide({ singletons: [getQueryClient('page'), JobsApi, JobsStore] })`}

    {data?.map(job => (
  • {job.title}

    {job.description}

  • ))}
); }) ); const Page1 = () => { return (

Page 1

); }; const Page2 = () => { return (

Page 2

); }; export const PageExample = () => { const [page, setPage] = useState(1); const [showApp, setShowApp] = useState(false); return (

In this example are two pages, each containing two MFE components. The MFE component uses a query to fetch job listings, and provides a 'page' QueryClient.

You will notice in the console that when the page first loads, only one fetch occurs for both components on the page because the query is deduped.

When you navigate to another page, a fetch occurs again. This is because when a Page unmounts, there are no longer any Queries using the 'page' QueryClient. And when that happens, the 'page' cache is removed. Then when the next Page component mounts, along with MFE components using 'page' QueryClients, the 'page' cache is recreated anew.


{!showApp && ( )} {showApp && ( {page === 1 && } {page === 2 && } )}
); };