facebook / facebook/relay

usePaginationFragment's refetch triggers twice when using useTransition

Open
#3,082 7 comments 2 reactions 0 assignees View on GitHub
bug
Dominant language
Rust
Stars
19k
Forks
1.9k
PR merge metrics
No merged PRs in 30d

Description

I'm using the following `experimental` versions when running encountering this issue.

```
"react": "0.0.0-experimental-f42431abe"
"react-dom": "0.0.0-experimental-f42431abe"
"react-relay": "0.0.0-experimental-8cc94ddc"
```

I've been following the reference and seem to be hitting a strange bug. https://relay.dev/docs/en/experimental/api-reference#usepaginationfragment

I'm loading a component which is supplied with preloaded data, I'm then displaying that data in a list and allowing a user to change the `orderStatus` as a filter for that data.

I'm using the `usePaginationFragment` hook and the `refetch` method from that. All of that seems to work as intended but does suspend the component which is expected.

Applying a `useTransition` hook around the `refetch` causes some strange behaviour.

It seems the first change works as intended, but subsequent changes causes the `refetch` to trigger again and call the `onComplete` method.

I've tried commenting out the `startTransition` and it works fine but suspends, enabling it again causes `refetch` to trigger twice.

```
const queryData = usePreloadedQuery(QUERY, ordersQuery);
const {
data: { orders },
refetch,
loadNext,
hasNext,
isLoadingNext,
} = usePaginationFragment(REFETCHABLE, queryData);
const [startTransition, isPending] = useTransition({ timeoutMs: 10 * 1000 });
const [orderStatus, setOrderStatus] = useState('all');
const handleOrderStatusChange = (key) => {
console.log(`TRANSITION:${key}`);
startTransition(() => {
setOrderStatus(key);
console.log(`REFETCH:${key}`);
refetch({
count: ordersQuery?.variables?.count,
cursor: null,
orderStatus: key,
startDate,
}, {
fetchPolicy: 'network-only',
onComplete: () => console.log(`COMPLETE:${key}`),
});
});
};

console.log('RENDER', { orders: orders?.edges?.length, orderStatus, startDate });
```

In the code above, following these steps it reproduces the issue.

- Changing filter from `all` to `open`
- `TRANSITION:open`, `REFETCH:open`, ``, `COMPLETE:open`
- Changing the filter from `open` to `complete`
- `TRANSITION:complete`, `REFETCH:complete`, ``, `COMPLETE:open`, ``, `COMPLETE:complete`
- Changing the filter from `complete` to `all`
- `TRANSITION:all`, `REFETCH:all`, ``, `COMPLETE:complete`, ``, `COMPLETE:all`

The initial load appears to work just fine, but any changes after that cause duplicate requests to be sent. The strange part is it's not like the function in `startTransition` is calling twice else you'd see `REFETCH` called twice as well, so it's just the `refetch` function itself calling some how, which then calls the `onComplete` callback function.

Any help with this would be greatly appreciated, let me know if you require any further details.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.