Summary
loadNext from usePaginationFragment silently no-ops when the parent query is active, even after it completes, because the callback closes over a stale isParentQueryActive value.
Versions
react-relay@18.2.0 through react-relay@20.1.1 (current main)
The Problem
The loadMore callback includes isRequestInvalid (which depends on isParentQueryActive) in its useCallback dependency array. When the parent query completes, isParentQueryActive changes from true → false, triggering a callback recreation. However, if loadNext is called before the re-render occurs, it uses the old callback with the stale isParentQueryActive = true value.
Files involved
Reproduction
const { data, loadNext, hasNext, isLoadingNext } = usePaginationFragment(
graphql`
fragment FeedList on Query @refetchable(queryName: "FeedListRefetch") {
feed(first: $first) @connection(key: "FeedList_feed") { ... }
}
`,
queryRef
);
// Try to paginate on mount
useEffect(() => {
if (hasNext && !isLoadingNext) {
loadNext(10); // ❌ Silently fails - returns { dispose: () => {} }
}
}, [hasNext, isLoadingNext, loadNext]);
Summary
loadNextfrom usePaginationFragment silently no-ops when the parent query is active, even after it completes, because the callback closes over a staleisParentQueryActivevalue.Versions
react-relay@18.2.0 through react-relay@20.1.1 (current main)
The Problem
The
loadMorecallback includesisRequestInvalid(which depends onisParentQueryActive) in its useCallback dependency array. When the parent query completes,isParentQueryActivechanges from true → false, triggering a callback recreation. However, ifloadNextis called before the re-render occurs, it uses the old callback with the stale isParentQueryActive = true value.Files involved
Reproduction