react-relay 18.1.0 → 18.2.0
Sign up to get free protection for your applications and to get access to all the features.
- package/ReactRelayContext.js +1 -1
- package/ReactRelayFragmentContainer.js.flow +2 -5
- package/hooks.js +1 -1
- package/index.js +1 -1
- package/index.js.flow +3 -0
- package/legacy.js +1 -1
- package/lib/index.js +2 -0
- package/lib/relay-hooks/legacy/FragmentResource.js +1 -2
- package/lib/relay-hooks/loadQuery.js +5 -14
- package/lib/relay-hooks/useFragmentInternal_CURRENT.js +1 -2
- package/lib/relay-hooks/useFragmentInternal_EXPERIMENTAL.js +1 -2
- package/lib/relay-hooks/usePrefetchableForwardPaginationFragment_EXPERIMENTAL.js +227 -0
- package/package.json +2 -2
- package/react-relay-hooks.js +2 -2
- package/react-relay-hooks.min.js +2 -2
- package/react-relay-legacy.js +1 -1
- package/react-relay-legacy.min.js +1 -1
- package/react-relay.js +2 -2
- package/react-relay.min.js +2 -2
- package/relay-hooks/EntryPointTypes.flow.js.flow +2 -2
- package/relay-hooks/MatchContainer.js.flow +1 -1
- package/relay-hooks/legacy/FragmentResource.js.flow +2 -3
- package/relay-hooks/loadQuery.js.flow +30 -38
- package/relay-hooks/useFragmentInternal_CURRENT.js.flow +5 -7
- package/relay-hooks/useFragmentInternal_EXPERIMENTAL.js.flow +5 -7
- package/relay-hooks/usePrefetchableForwardPaginationFragment_EXPERIMENTAL.js.flow +433 -0
@@ -14,6 +14,7 @@
|
|
14
14
|
import type {QueryResult} from './QueryResource';
|
15
15
|
import type {
|
16
16
|
CacheConfig,
|
17
|
+
DataID,
|
17
18
|
FetchPolicy,
|
18
19
|
IEnvironment,
|
19
20
|
ReaderFragment,
|
@@ -21,10 +22,7 @@ import type {
|
|
21
22
|
SelectorData,
|
22
23
|
Snapshot,
|
23
24
|
} from 'relay-runtime';
|
24
|
-
import type {
|
25
|
-
MissingClientEdgeRequestInfo,
|
26
|
-
MissingLiveResolverField,
|
27
|
-
} from 'relay-runtime/store/RelayStoreTypes';
|
25
|
+
import type {MissingClientEdgeRequestInfo} from 'relay-runtime/store/RelayStoreTypes';
|
28
26
|
|
29
27
|
const {getQueryResourceForEnvironment} = require('./QueryResource');
|
30
28
|
const useRelayEnvironment = require('./useRelayEnvironment');
|
@@ -101,13 +99,13 @@ function getMissingClientEdges(
|
|
101
99
|
|
102
100
|
function getSuspendingLiveResolver(
|
103
101
|
state: FragmentState,
|
104
|
-
): $ReadOnlyArray<
|
102
|
+
): $ReadOnlyArray<DataID> | null {
|
105
103
|
if (state.kind === 'bailout') {
|
106
104
|
return null;
|
107
105
|
} else if (state.kind === 'singular') {
|
108
106
|
return state.snapshot.missingLiveResolverFields ?? null;
|
109
107
|
} else {
|
110
|
-
let missingFields: null | Array<
|
108
|
+
let missingFields: null | Array<DataID> = null;
|
111
109
|
for (const snapshot of state.snapshots) {
|
112
110
|
if (snapshot.missingLiveResolverFields) {
|
113
111
|
missingFields = missingFields ?? [];
|
@@ -523,7 +521,7 @@ hook useFragmentInternal_EXPERIMENTAL(
|
|
523
521
|
const suspendingLiveResolvers = getSuspendingLiveResolver(state);
|
524
522
|
if (suspendingLiveResolvers != null && suspendingLiveResolvers.length > 0) {
|
525
523
|
throw Promise.all(
|
526
|
-
suspendingLiveResolvers.map(
|
524
|
+
suspendingLiveResolvers.map(liveStateID => {
|
527
525
|
// $FlowFixMe[prop-missing] This is expected to be a RelayModernStore
|
528
526
|
return environment.getStore().getLiveResolverPromise(liveStateID);
|
529
527
|
}),
|
@@ -0,0 +1,433 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
3
|
+
*
|
4
|
+
* This source code is licensed under the MIT license found in the
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
6
|
+
*
|
7
|
+
* @flow strict-local
|
8
|
+
* @format
|
9
|
+
* @oncall relay
|
10
|
+
*/
|
11
|
+
|
12
|
+
'use strict';
|
13
|
+
|
14
|
+
import type {RefetchFn} from './useRefetchableFragment';
|
15
|
+
import type {Options} from './useRefetchableFragmentInternal';
|
16
|
+
import type {FragmentType, Variables} from 'relay-runtime';
|
17
|
+
import type {PrefetchableRefetchableFragment} from 'relay-runtime';
|
18
|
+
|
19
|
+
const useFragment = require('./useFragment');
|
20
|
+
const useLoadMoreFunction = require('./useLoadMoreFunction');
|
21
|
+
const useRefetchableFragmentInternal = require('./useRefetchableFragmentInternal');
|
22
|
+
const useRelayEnvironment = require('./useRelayEnvironment');
|
23
|
+
const useStaticFragmentNodeWarning = require('./useStaticFragmentNodeWarning');
|
24
|
+
const invariant = require('invariant');
|
25
|
+
const {
|
26
|
+
useCallback,
|
27
|
+
useDebugValue,
|
28
|
+
useEffect,
|
29
|
+
useLayoutEffect,
|
30
|
+
useMemo,
|
31
|
+
useRef,
|
32
|
+
useState,
|
33
|
+
} = require('react');
|
34
|
+
const {
|
35
|
+
getFragment,
|
36
|
+
getFragmentIdentifier,
|
37
|
+
getPaginationMetadata,
|
38
|
+
} = require('relay-runtime');
|
39
|
+
const {
|
40
|
+
ConnectionInterface,
|
41
|
+
getSelector,
|
42
|
+
getValueAtPath,
|
43
|
+
} = require('relay-runtime');
|
44
|
+
|
45
|
+
type LoadMoreFn<TVariables: Variables> = (
|
46
|
+
count: number,
|
47
|
+
options?: {
|
48
|
+
onComplete?: (Error | null) => void,
|
49
|
+
UNSTABLE_extraVariables?: Partial<TVariables>,
|
50
|
+
},
|
51
|
+
) => void;
|
52
|
+
|
53
|
+
export type ReturnType<TVariables, TData, TEdgeData, TKey> = {
|
54
|
+
// NOTE: This type ensures that the type of the returned data is either:
|
55
|
+
// - nullable if the provided ref type is nullable
|
56
|
+
// - non-nullable if the provided ref type is non-nullable
|
57
|
+
data: [+key: TKey] extends [+key: {+$fragmentSpreads: mixed, ...}]
|
58
|
+
? TData
|
59
|
+
: ?TData,
|
60
|
+
loadNext: LoadMoreFn<TVariables>,
|
61
|
+
hasNext: boolean,
|
62
|
+
isLoadingNext: boolean,
|
63
|
+
refetch: RefetchFn<TVariables, TKey>,
|
64
|
+
edges: TEdgeData,
|
65
|
+
};
|
66
|
+
|
67
|
+
type LoadMoreOptions<TVariables> = {
|
68
|
+
UNSTABLE_extraVariables?: Partial<TVariables>,
|
69
|
+
onComplete?: (Error | null) => void,
|
70
|
+
};
|
71
|
+
|
72
|
+
export type GetExtraVariablesFn<TEdgeData, TData, TVariables, TKey> = ({
|
73
|
+
hasNext: boolean,
|
74
|
+
data: [+key: TKey] extends [+key: {+$fragmentSpreads: mixed, ...}]
|
75
|
+
? TData
|
76
|
+
: ?TData,
|
77
|
+
getServerEdges: () => TEdgeData,
|
78
|
+
}) => Partial<TVariables>;
|
79
|
+
|
80
|
+
hook usePrefetchableForwardPaginationFragment_EXPERIMENTAL<
|
81
|
+
TFragmentType: FragmentType,
|
82
|
+
TVariables: Variables,
|
83
|
+
TData,
|
84
|
+
TEdgeData,
|
85
|
+
TKey: ?{+$fragmentSpreads: TFragmentType, ...},
|
86
|
+
>(
|
87
|
+
fragmentInput: PrefetchableRefetchableFragment<
|
88
|
+
TFragmentType,
|
89
|
+
TData,
|
90
|
+
TEdgeData,
|
91
|
+
TVariables,
|
92
|
+
>,
|
93
|
+
parentFragmentRef: TKey,
|
94
|
+
bufferSize: number,
|
95
|
+
initialSize?: ?number,
|
96
|
+
prefetchingLoadMoreOptions?: {
|
97
|
+
UNSTABLE_extraVariables?:
|
98
|
+
| Partial<TVariables>
|
99
|
+
| GetExtraVariablesFn<TEdgeData, TData, TVariables, TKey>,
|
100
|
+
onComplete?: (Error | null) => void,
|
101
|
+
},
|
102
|
+
minimalFetchSize: number = 1,
|
103
|
+
): ReturnType<TVariables, TData, TEdgeData, TKey> {
|
104
|
+
const fragmentNode = getFragment(fragmentInput);
|
105
|
+
useStaticFragmentNodeWarning(
|
106
|
+
fragmentNode,
|
107
|
+
'first argument of usePrefetchableForwardPaginationFragment_EXPERIMENTAL()',
|
108
|
+
);
|
109
|
+
const componentDisplayName =
|
110
|
+
'usePrefetchableForwardPaginationFragment_EXPERIMENTAL()';
|
111
|
+
|
112
|
+
const {connectionPathInFragmentData, paginationRequest, paginationMetadata} =
|
113
|
+
getPaginationMetadata(fragmentNode, componentDisplayName);
|
114
|
+
|
115
|
+
const {fragmentData, fragmentRef, refetch} = useRefetchableFragmentInternal<
|
116
|
+
{variables: TVariables, response: TData},
|
117
|
+
{data?: TData},
|
118
|
+
>(fragmentNode, parentFragmentRef, componentDisplayName);
|
119
|
+
// TODO: Get rid of `getFragmentIdentifier`
|
120
|
+
const fragmentIdentifier = getFragmentIdentifier(fragmentNode, fragmentRef);
|
121
|
+
|
122
|
+
const edgeKeys = useMemo(() => {
|
123
|
+
const connection = getValueAtPath(
|
124
|
+
fragmentData,
|
125
|
+
connectionPathInFragmentData,
|
126
|
+
);
|
127
|
+
if (connection == null) {
|
128
|
+
return null;
|
129
|
+
}
|
130
|
+
const {EDGES} = ConnectionInterface.get();
|
131
|
+
// $FlowFixMe[incompatible-use]
|
132
|
+
return connection[EDGES];
|
133
|
+
}, [connectionPathInFragmentData, fragmentData]);
|
134
|
+
|
135
|
+
const sourceSize = edgeKeys == null ? -1 : edgeKeys.length;
|
136
|
+
|
137
|
+
const [_numInUse, setNumInUse] = useState(
|
138
|
+
initialSize != null ? initialSize : sourceSize,
|
139
|
+
);
|
140
|
+
let numInUse = _numInUse;
|
141
|
+
// We can only reset the source size when the component is
|
142
|
+
// updated with new edgeKeys
|
143
|
+
if (_numInUse === -1 && sourceSize !== -1) {
|
144
|
+
numInUse = initialSize != null ? initialSize : sourceSize;
|
145
|
+
setNumInUse(numInUse);
|
146
|
+
}
|
147
|
+
|
148
|
+
const environment = useRelayEnvironment();
|
149
|
+
const [isLoadingMore, reallySetIsLoadingMore] = useState(false);
|
150
|
+
const [isRefetching, setIsRefetching] = useState(false);
|
151
|
+
const availableSizeRef = useRef(0);
|
152
|
+
// Schedule this update since it must be observed by components at the same
|
153
|
+
// batch as when hasNext changes. hasNext is read from the store and store
|
154
|
+
// updates are scheduled, so this must be scheduled too.
|
155
|
+
const setIsLoadingMore = useCallback(
|
156
|
+
(value: boolean) => {
|
157
|
+
const schedule = environment.getScheduler()?.schedule;
|
158
|
+
if (schedule) {
|
159
|
+
schedule(() => {
|
160
|
+
reallySetIsLoadingMore(value);
|
161
|
+
});
|
162
|
+
} else {
|
163
|
+
reallySetIsLoadingMore(value);
|
164
|
+
}
|
165
|
+
},
|
166
|
+
[environment],
|
167
|
+
);
|
168
|
+
|
169
|
+
// `isLoadingMore` state is updated in a low priority, internally we need
|
170
|
+
// to synchronously get the loading state to decide whether to load more
|
171
|
+
const isLoadingMoreRef = useRef(false);
|
172
|
+
|
173
|
+
const observer = useMemo(
|
174
|
+
() => ({
|
175
|
+
start: () => {
|
176
|
+
isLoadingMoreRef.current = true;
|
177
|
+
// We want to make sure that `isLoadingMore` is updated immediately, to avoid
|
178
|
+
// product code triggering multiple `loadMore` calls
|
179
|
+
reallySetIsLoadingMore(true);
|
180
|
+
},
|
181
|
+
complete: () => {
|
182
|
+
isLoadingMoreRef.current = false;
|
183
|
+
setIsLoadingMore(false);
|
184
|
+
},
|
185
|
+
error: () => {
|
186
|
+
isLoadingMoreRef.current = false;
|
187
|
+
setIsLoadingMore(false);
|
188
|
+
},
|
189
|
+
}),
|
190
|
+
[setIsLoadingMore],
|
191
|
+
);
|
192
|
+
const handleReset = useCallback(() => {
|
193
|
+
if (!isRefetching) {
|
194
|
+
// Do not reset items count during refetching
|
195
|
+
const schedule = environment.getScheduler()?.schedule;
|
196
|
+
if (schedule) {
|
197
|
+
schedule(() => {
|
198
|
+
setNumInUse(-1);
|
199
|
+
});
|
200
|
+
} else {
|
201
|
+
setNumInUse(-1);
|
202
|
+
}
|
203
|
+
}
|
204
|
+
isLoadingMoreRef.current = false;
|
205
|
+
setIsLoadingMore(false);
|
206
|
+
}, [environment, isRefetching, setIsLoadingMore]);
|
207
|
+
|
208
|
+
const [loadMore, hasNext, disposeFetchNext] = useLoadMoreFunction<TVariables>(
|
209
|
+
{
|
210
|
+
componentDisplayName,
|
211
|
+
connectionPathInFragmentData,
|
212
|
+
direction: 'forward',
|
213
|
+
fragmentData,
|
214
|
+
fragmentIdentifier,
|
215
|
+
fragmentNode,
|
216
|
+
fragmentRef,
|
217
|
+
paginationMetadata,
|
218
|
+
paginationRequest,
|
219
|
+
observer,
|
220
|
+
onReset: handleReset,
|
221
|
+
},
|
222
|
+
);
|
223
|
+
|
224
|
+
useLayoutEffect(() => {
|
225
|
+
// Make sure `availableSize` is updated before `showMore` from current render can be called
|
226
|
+
availableSizeRef.current = sourceSize - numInUse;
|
227
|
+
}, [numInUse, sourceSize]);
|
228
|
+
|
229
|
+
const prefetchingUNSTABLE_extraVariables =
|
230
|
+
prefetchingLoadMoreOptions?.UNSTABLE_extraVariables;
|
231
|
+
const prefetchingOnComplete = prefetchingLoadMoreOptions?.onComplete;
|
232
|
+
|
233
|
+
const showMore = useCallback(
|
234
|
+
(numToAdd: number, options?: LoadMoreOptions<TVariables>) => {
|
235
|
+
// Matches the behavior of `usePaginationFragment`. If there is a `loadMore` ongoing,
|
236
|
+
// the hook handles making the `loadMore` a no-op.
|
237
|
+
if (!isLoadingMoreRef.current || availableSizeRef.current >= 0) {
|
238
|
+
// Preemtively update `availableSizeRef`, so if two `loadMore` is called in the same tick,
|
239
|
+
// a second `loadMore` can be no-op
|
240
|
+
availableSizeRef.current -= numToAdd;
|
241
|
+
|
242
|
+
setNumInUse(lastNumInUse => {
|
243
|
+
return lastNumInUse + numToAdd;
|
244
|
+
});
|
245
|
+
|
246
|
+
// If the product needs more items from network, load the amount needed to fullfil
|
247
|
+
// the requirement and cache, capped at the current amount defined by product
|
248
|
+
if (!isLoadingMoreRef.current && availableSizeRef.current < 0) {
|
249
|
+
loadMore(
|
250
|
+
Math.max(
|
251
|
+
minimalFetchSize,
|
252
|
+
Math.min(numToAdd, bufferSize - availableSizeRef.current),
|
253
|
+
),
|
254
|
+
// Keep options For backward compatibility
|
255
|
+
options ?? {
|
256
|
+
onComplete: prefetchingOnComplete,
|
257
|
+
UNSTABLE_extraVariables:
|
258
|
+
typeof prefetchingUNSTABLE_extraVariables === 'function'
|
259
|
+
? // $FlowFixMe[incompatible-call]
|
260
|
+
prefetchingUNSTABLE_extraVariables({
|
261
|
+
hasNext,
|
262
|
+
// $FlowFixMe[incompatible-call]
|
263
|
+
data: fragmentData,
|
264
|
+
getServerEdges: () => {
|
265
|
+
const selector = getSelector(
|
266
|
+
// $FlowFixMe[incompatible-call]
|
267
|
+
edgesFragment,
|
268
|
+
edgeKeys,
|
269
|
+
);
|
270
|
+
if (selector == null) {
|
271
|
+
// $FlowFixMe[incompatible-call]
|
272
|
+
return [];
|
273
|
+
}
|
274
|
+
invariant(
|
275
|
+
selector.kind === 'PluralReaderSelector',
|
276
|
+
'Expected a plural selector',
|
277
|
+
);
|
278
|
+
// $FlowFixMe[incompatible-call]
|
279
|
+
return selector.selectors.map(
|
280
|
+
sel => environment.lookup(sel).data,
|
281
|
+
);
|
282
|
+
},
|
283
|
+
})
|
284
|
+
: prefetchingUNSTABLE_extraVariables,
|
285
|
+
},
|
286
|
+
);
|
287
|
+
}
|
288
|
+
}
|
289
|
+
},
|
290
|
+
[
|
291
|
+
bufferSize,
|
292
|
+
loadMore,
|
293
|
+
minimalFetchSize,
|
294
|
+
edgeKeys,
|
295
|
+
fragmentData,
|
296
|
+
prefetchingUNSTABLE_extraVariables,
|
297
|
+
prefetchingOnComplete,
|
298
|
+
],
|
299
|
+
);
|
300
|
+
|
301
|
+
const edgesFragment = fragmentInput.metadata?.refetch?.edgesFragment;
|
302
|
+
invariant(
|
303
|
+
edgesFragment != null,
|
304
|
+
'usePrefetchableForwardPaginationFragment_EXPERIMENTAL: Expected the edge fragment to be defined, ' +
|
305
|
+
'please make sure you have added `prefetchable_pagination: true` to `@connection`',
|
306
|
+
);
|
307
|
+
|
308
|
+
// Always try to keep `bufferSize` items in the buffer
|
309
|
+
// Or load the number of items that have been registred to show
|
310
|
+
useEffect(() => {
|
311
|
+
if (
|
312
|
+
// Check the ref to avoid infinite `loadMore`, when a `loadMore` has started,
|
313
|
+
// but `isLoadingMore` isn't updated
|
314
|
+
!isLoadingMoreRef.current &&
|
315
|
+
// Check the original `isLoadingMore` so when `loadMore` is called, the internal
|
316
|
+
// `loadMore` hook has been updated with the latest cursor
|
317
|
+
!isLoadingMore &&
|
318
|
+
!isRefetching &&
|
319
|
+
hasNext &&
|
320
|
+
(sourceSize - numInUse < bufferSize || numInUse > sourceSize)
|
321
|
+
) {
|
322
|
+
const onComplete = prefetchingOnComplete;
|
323
|
+
loadMore(
|
324
|
+
Math.max(
|
325
|
+
bufferSize - Math.max(sourceSize - numInUse, 0),
|
326
|
+
numInUse - sourceSize,
|
327
|
+
minimalFetchSize,
|
328
|
+
),
|
329
|
+
{
|
330
|
+
onComplete,
|
331
|
+
UNSTABLE_extraVariables:
|
332
|
+
typeof prefetchingUNSTABLE_extraVariables === 'function'
|
333
|
+
? // $FlowFixMe[incompatible-call]
|
334
|
+
prefetchingUNSTABLE_extraVariables({
|
335
|
+
hasNext,
|
336
|
+
// $FlowFixMe[incompatible-call]
|
337
|
+
data: fragmentData,
|
338
|
+
getServerEdges: () => {
|
339
|
+
const selector = getSelector(edgesFragment, edgeKeys);
|
340
|
+
if (selector == null) {
|
341
|
+
// $FlowFixMe[incompatible-call]
|
342
|
+
return [];
|
343
|
+
}
|
344
|
+
invariant(
|
345
|
+
selector.kind === 'PluralReaderSelector',
|
346
|
+
'Expected a plural selector',
|
347
|
+
);
|
348
|
+
// $FlowFixMe[incompatible-call]
|
349
|
+
return selector.selectors.map(
|
350
|
+
sel => environment.lookup(sel).data,
|
351
|
+
);
|
352
|
+
},
|
353
|
+
})
|
354
|
+
: prefetchingUNSTABLE_extraVariables,
|
355
|
+
},
|
356
|
+
);
|
357
|
+
}
|
358
|
+
}, [
|
359
|
+
hasNext,
|
360
|
+
bufferSize,
|
361
|
+
isRefetching,
|
362
|
+
loadMore,
|
363
|
+
numInUse,
|
364
|
+
prefetchingUNSTABLE_extraVariables,
|
365
|
+
prefetchingOnComplete,
|
366
|
+
sourceSize,
|
367
|
+
edgeKeys,
|
368
|
+
isLoadingMore,
|
369
|
+
minimalFetchSize,
|
370
|
+
environment,
|
371
|
+
edgesFragment,
|
372
|
+
]);
|
373
|
+
|
374
|
+
const realNumInUse = Math.min(numInUse, sourceSize);
|
375
|
+
|
376
|
+
const derivedEdgeKeys: $ReadOnlyArray<mixed> = useMemo(
|
377
|
+
() => edgeKeys?.slice(0, realNumInUse) ?? [],
|
378
|
+
[edgeKeys, realNumInUse],
|
379
|
+
);
|
380
|
+
|
381
|
+
// $FlowExpectedError[incompatible-call] - we know derivedEdgeKeys are the correct keys
|
382
|
+
const edges: TEdgeData = useFragment(edgesFragment, derivedEdgeKeys);
|
383
|
+
|
384
|
+
const refetchPagination = useCallback(
|
385
|
+
(variables: TVariables, options?: Options) => {
|
386
|
+
disposeFetchNext();
|
387
|
+
setIsRefetching(true);
|
388
|
+
return refetch(variables, {
|
389
|
+
...options,
|
390
|
+
onComplete: maybeError => {
|
391
|
+
// Need to be batched with the store update
|
392
|
+
const schedule = environment.getScheduler()?.schedule;
|
393
|
+
if (schedule) {
|
394
|
+
schedule(() => {
|
395
|
+
setIsRefetching(false);
|
396
|
+
setNumInUse(-1);
|
397
|
+
});
|
398
|
+
} else {
|
399
|
+
setIsRefetching(false);
|
400
|
+
setNumInUse(-1);
|
401
|
+
}
|
402
|
+
options?.onComplete?.(maybeError);
|
403
|
+
},
|
404
|
+
__environment: undefined,
|
405
|
+
});
|
406
|
+
},
|
407
|
+
[disposeFetchNext, environment, refetch],
|
408
|
+
);
|
409
|
+
|
410
|
+
if (__DEV__) {
|
411
|
+
// $FlowFixMe[react-rule-hook]
|
412
|
+
useDebugValue({
|
413
|
+
fragment: fragmentNode.name,
|
414
|
+
data: fragmentData,
|
415
|
+
hasNext,
|
416
|
+
isLoadingNext: isLoadingMore,
|
417
|
+
});
|
418
|
+
}
|
419
|
+
|
420
|
+
return {
|
421
|
+
edges,
|
422
|
+
// $FlowFixMe[incompatible-return]
|
423
|
+
data: fragmentData,
|
424
|
+
loadNext: showMore,
|
425
|
+
hasNext: hasNext || sourceSize > numInUse,
|
426
|
+
// Only reflect `isLoadingMore` if the product depends on it, do not refelect
|
427
|
+
// `isLoaindgMore` state if it is for fufilling the buffer
|
428
|
+
isLoadingNext: isLoadingMore && numInUse > sourceSize,
|
429
|
+
refetch: refetchPagination,
|
430
|
+
};
|
431
|
+
}
|
432
|
+
|
433
|
+
module.exports = usePrefetchableForwardPaginationFragment_EXPERIMENTAL;
|