diff --git a/examples/with-defer-stream-directives/src/App.jsx b/examples/with-defer-stream-directives/src/App.jsx
index 3e29e59ded..4043a89ca1 100644
--- a/examples/with-defer-stream-directives/src/App.jsx
+++ b/examples/with-defer-stream-directives/src/App.jsx
@@ -21,7 +21,9 @@ const client = new Client({
function App() {
return (
-
+ Loading...
}>
+
+
);
}
diff --git a/examples/with-defer-stream-directives/src/Songs.jsx b/examples/with-defer-stream-directives/src/Songs.jsx
index a61b02a2ed..cd5dfb202d 100644
--- a/examples/with-defer-stream-directives/src/Songs.jsx
+++ b/examples/with-defer-stream-directives/src/Songs.jsx
@@ -13,6 +13,9 @@ const SONGS_QUERY = gql`
firstVerse
...secondVerseFields @defer
}
+ alphabet @stream(initialCount: 3) {
+ char
+ }
}
${SecondVerseFragment}
@@ -50,6 +53,9 @@ const LocationsList = () => {
{data && (
<>
+ {data.alphabet.map(i => (
+ {i.char}
+ ))}
>
)}
diff --git a/packages/react-urql/src/hooks/cache.ts b/packages/react-urql/src/hooks/cache.ts
index db6ddc3b77..52a162d181 100644
--- a/packages/react-urql/src/hooks/cache.ts
+++ b/packages/react-urql/src/hooks/cache.ts
@@ -1,7 +1,15 @@
import { pipe, subscribe } from 'wonka';
import type { Client, OperationResult } from '@urql/core';
-type CacheEntry = OperationResult | Promise | undefined;
+export type FragmentPromise = Promise & {
+ _resolve: () => void;
+ _resolved: boolean;
+};
+type CacheEntry =
+ | OperationResult
+ | Promise
+ | FragmentPromise
+ | undefined;
interface Cache {
get(key: number): CacheEntry;
diff --git a/packages/react-urql/src/hooks/useFragment.ts b/packages/react-urql/src/hooks/useFragment.ts
index e612110c79..3913eadffc 100644
--- a/packages/react-urql/src/hooks/useFragment.ts
+++ b/packages/react-urql/src/hooks/useFragment.ts
@@ -19,6 +19,7 @@ import type {
import { useClient } from '../context';
import { useRequest } from './useRequest';
+import type { FragmentPromise } from './cache';
import { getCacheForClient } from './cache';
import { hasDepsChanged } from './state';
@@ -172,7 +173,12 @@ export function useFragment(
cache.set(request.key, newResult.data as any);
return { data: newResult.data as any, fetching: false };
} else if (suspense) {
- const promise = new Promise(() => {});
+ let _resolve;
+ const promise = new Promise(res => {
+ _resolve = res;
+ }) as FragmentPromise;
+ promise._resolve = _resolve;
+ promise._resolved = false;
cache.set(request.key, promise);
throw promise;
} else {
@@ -182,6 +188,14 @@ export function useFragment(
throw cached;
}
+ if (
+ '_resolve' in cached &&
+ '_resolved' in cached &&
+ !cached._resolved &&
+ typeof cached._resolve == 'function'
+ ) {
+ cached._resolve();
+ }
return { fetching: false, data: (cached as OperationResult).data };
},
[cache, request]