From 84982efe65362ebc99d7f02624d21b3a4777624b Mon Sep 17 00:00:00 2001 From: Ahmed Tarek Date: Mon, 31 Jan 2022 23:43:07 +0200 Subject: [PATCH] fix executing standby queries in ssr --- src/react/hooks/useQuery.ts | 79 +++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 30 deletions(-) diff --git a/src/react/hooks/useQuery.ts b/src/react/hooks/useQuery.ts index 363ca3ba3a3..7f55b378154 100644 --- a/src/react/hooks/useQuery.ts +++ b/src/react/hooks/useQuery.ts @@ -1,7 +1,7 @@ import { useContext, useEffect, useMemo, useRef, useState } from 'react'; import { equal } from '@wry/equality'; import { OperationVariables, mergeOptions } from '../../core'; -import { getApolloContext } from '../context'; +import { ApolloContextValue, getApolloContext } from '../context'; import { ApolloError } from '../../errors'; import { ApolloQueryResult, @@ -53,37 +53,13 @@ export function useQuery< if ( context.renderPromises && + options?.fetchPolicy !== "standby" && options?.ssr !== false && !options?.skip && obsQuery.getCurrentResult().loading ) { // TODO: This is a legacy API which could probably be cleaned up - context.renderPromises.addQueryPromise( - { - // The only options which seem to actually be used by the - // RenderPromises class are query and variables. - getOptions: () => createWatchQueryOptions(query, options, defaultWatchQueryOptions), - fetchData: () => new Promise((resolve) => { - const sub = obsQuery!.subscribe({ - next(result) { - if (!result.loading) { - resolve() - sub.unsubscribe(); - } - }, - error() { - resolve(); - sub.unsubscribe(); - }, - complete() { - resolve(); - }, - }); - }), - }, - // This callback never seemed to do anything - () => null, - ); + addSSRQueryPromise(context, watchQueryOptions, obsQuery) } return obsQuery; @@ -244,15 +220,19 @@ export function useQuery< obsQuery.refetch(); } - // TODO: This is a hack to make sure useLazyQuery executions update the - // obsevable query options for ssr. + // TODO: This is a hack to make sure useLazyQuery executions update the + // observable query options for ssr. if ( context.renderPromises && options?.ssr !== false && !options?.skip && result.loading ) { - obsQuery.setOptions(createWatchQueryOptions(query, options, defaultWatchQueryOptions)).catch(() => {}); + const watchQueryOptions = createWatchQueryOptions(query, options, defaultWatchQueryOptions); + if (!equal(ref.current.watchQueryOptions, watchQueryOptions)) { + obsQuery.setOptions(watchQueryOptions).catch(() => {}); + addSSRQueryPromise(context, watchQueryOptions, obsQuery) + } } // We assign options during rendering as a guard to make sure that @@ -370,3 +350,42 @@ function createWatchQueryOptions( return watchQueryOptions; } + +/** + * Function to add query promise in ssr + */ + +function addSSRQueryPromise( + context: ApolloContextValue, + options: QueryHookOptions = {}, + obsQuery: ObservableQuery +): void { + if(!context.renderPromises) return; + context.renderPromises.addQueryPromise( + { + // The only options which seem to actually be used by the + // RenderPromises class are query and variables. + getOptions: () => options, + fetchData: () => + new Promise((resolve) => { + const sub = obsQuery!.subscribe({ + next(result) { + if (!result.loading) { + resolve(); + sub.unsubscribe(); + } + }, + error() { + resolve(); + sub.unsubscribe(); + }, + complete() { + resolve(); + }, + }); + }), + }, + // This callback never seemed to do anything + () => null + ); +} \ No newline at end of file