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