facebook / facebook/relay

usePaginationFragment: `loadNext` silently fails due to stale closure over `isParentQueryActive`

Open
#5,111 0 comments 0 reactions 0 assignees View on GitHub
shared with relay team
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.