usePaginationFragment: `loadNext` silently fails due to stale closure over `isParentQueryActive`
- Dominant language
- Rust
- Stars
- 19k
- Forks
- 1.9k
- PR merge metrics
- No merged PRs in 30d
Description
**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**
- https://github.com/facebook/relay/blob/main/packages/react-relay/relay-hooks/useLoadMoreFunction.js#L118 - isParentQueryActive captured in closure
- https://github.com/facebook/relay/blob/main/packages/react-relay/relay-hooks/useLoadMoreFunction.js#L175 - Stale value checked here
- https://github.com/facebook/relay/blob/main/packages/react-relay/relay-hooks/useLoadMoreFunction.js#L273 - isRequestInvalid in dependency array
**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]);
```
Contributor guide
Research direction
Start with packages/react-relay/relay-hooks/useLoadMoreFunction.js, especially the closure near line 118, the check near line 175, and the dependency array near line 273. Run the provided usePaginationFragment reproduction and confirm that loadNext no longer silently returns a no-op when the parent query has just completed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, react
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100