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 { QueryClientStore } from '../utils/query-client.store'; 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 { globalClient: 'app', // Creates global application client queryKey: ['demo', 'jobs'], queryFn: async () => (await this.api?.get())?.data || [], }; } } const Jobs = provide({ singletons: [QueryClientStore, JobsApi, JobsStore], })( observer(() => { const [{ data, isLoading }] = useDependencies(JobsStore); if (isLoading) { return
Loading for 2 seconds...
; } return (

Jobs -{' '} {`provide({ singletons: [QueryClientStore, JobsApi, JobsStore] })`}

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

    {job.description}

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

Page 1

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

Page 2

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

In this example are two pages, each containing two Jobs components. The Jobs component uses a query to fetch job listings, and uses the 'app' 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.

Then when you navigate to the second page, no fetch occurs because the results of the query are cached.


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