diff --git a/web/components/contract/contract-page.tsx b/web/components/contract/contract-page.tsx index 0e86ad1d51..7f6f2d8fbd 100644 --- a/web/components/contract/contract-page.tsx +++ b/web/components/contract/contract-page.tsx @@ -74,6 +74,7 @@ import { SpiceCoin } from 'web/public/custom-components/spiceCoin' import { YourTrades } from 'web/pages/[username]/[contractSlug]' import { useSweepstakes } from '../sweepstakes-provider' import { useRouter } from 'next/router' +import { precacheAnswers } from 'web/hooks/use-answers' export function ContractPageContent(props: ContractParams) { const { @@ -190,6 +191,15 @@ export function ContractPageContent(props: ContractParams) { ) useSaveContractVisitsLocally(user === null, props.contract.id) + useEffect(() => { + if ('answers' in props.contract) { + precacheAnswers(props.contract.answers) + } + if (props.cash?.contract && 'answers' in props.cash.contract) { + precacheAnswers(props.cash.contract.answers) + } + }, []) + const playBetData = useBetData({ contractId: props.contract.id, outcomeType: props.contract.outcomeType, diff --git a/web/hooks/use-answers.ts b/web/hooks/use-answers.ts index 29a8586337..ecf67b0918 100644 --- a/web/hooks/use-answers.ts +++ b/web/hooks/use-answers.ts @@ -1,19 +1,12 @@ -import { useEffect, useState } from 'react' import { type Answer } from 'common/answer' +import { prepopulateCache, useAPIGetter } from './use-api-getter' import { useApiSubscription } from './use-api-subscription' -import { api } from 'web/lib/api/api' - -// TODO: use API getter export function useAnswer(answerId: string | undefined) { - const [answer, setAnswer] = useState() - useEffect(() => { - if (answerId) { - api('answer/:answerId', { - answerId, - }).then(setAnswer) - } - }, [answerId]) + const { data: answer, setData: setAnswer } = useAPIGetter( + 'answer/:answerId', + answerId ? { answerId } : undefined + ) return { answer, setAnswer } } @@ -33,3 +26,9 @@ export function useLiveAnswer(answerId: string | undefined) { return answer } + +export function precacheAnswers(answers: Answer[]) { + for (const answer of answers) { + prepopulateCache('answer/:answerId', { answerId: answer.id }, answer) + } +} diff --git a/web/hooks/use-api-getter.ts b/web/hooks/use-api-getter.ts index 4b088cbbc1..0d25db7808 100644 --- a/web/hooks/use-api-getter.ts +++ b/web/hooks/use-api-getter.ts @@ -6,6 +6,16 @@ import { useEvent } from './use-event' const promiseCache: Record | undefined> = {} +// Prepopulate cache with data, e.g. from static props +export function prepopulateCache

( + path: P, + props: APIParams

, + data: APIResponse

+) { + const key = `${path}-${JSON.stringify(props)}` + promiseCache[key] = Promise.resolve(data) +} + // react query at home export const useAPIGetter =

( path: P, @@ -24,7 +34,7 @@ export const useAPIGetter =

( APIResponse

| undefined >(undefined, `${overrideKey ?? path}`) - const key = `${path}-${propsString}-error` + const key = `${path}-${propsString}` const [error, setError] = usePersistentInMemoryState( undefined, key