Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

usePaginationFragment's refetch triggers twice when using useTransition #3082

Open
Sicria opened this issue May 20, 2020 · 7 comments
Open
Labels

Comments

@Sicria
Copy link

Sicria commented May 20, 2020

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, <REQUEST SENT:open>, COMPLETE:open
  • Changing the filter from open to complete
    • TRANSITION:complete, REFETCH:complete, <REQUEST SENT:open>, COMPLETE:open, <REQUEST SENT:complete>, COMPLETE:complete
  • Changing the filter from complete to all
    • TRANSITION:all, REFETCH:all, <REQUEST SENT:complete>, COMPLETE:complete, <REQUEST SENT:all>, 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.

@sibelius
Copy link
Contributor

I'm not sure if usePaginationFragment will suspend

but we got the same issue when using useRefetchableFragment

here https://github.com/sibelius/relay-workshop/blob/master/solutions/07-useRefetchableFragment/src/comment/PostComments.tsx#L71

@Sicria
Copy link
Author

Sicria commented May 21, 2020

Did you managed to fix it or come up with a workaround?

At the moment I've just commented out the transitions and let the component suspend, it's a horrible user experience but having the wrong data display is worse. Holding back on going live with it until I can figure out a solution to this.

@sibelius
Copy link
Contributor

one way to fix this is to move the suspend part to another component, and have another error boundary

@sibelius sibelius added the bug label Jun 5, 2020
@josephsavona
Copy link
Contributor

Thanks for the detailed issue, this definitely sounds like a bug. Just to confirm, were you using the absolute latest version of each package you mentioned?

@Sicria
Copy link
Author

Sicria commented Jun 9, 2020

At the time I believe these were the latest, although I see newer versions have been released since.

At this time I'm avoiding changing package versions as I've QA'd all of the functionality added with the experimental packages and upgrading to a newer experimental package would require a bit of work. So I'm holding off for a release version or enough changes on an experimental branch to justify the time to QA it all again.

@stale
Copy link

stale bot commented Dec 25, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Dec 25, 2020
@Zizico2
Copy link

Zizico2 commented Nov 16, 2023

Related? #4526

@stale stale bot removed the wontfix label Nov 16, 2023
danielstocks added a commit to danielstocks/relay that referenced this issue Nov 7, 2024
I found out that `useTransition` doesn't work when using `usePaginationFragement`. To get it to work the way it's intended in the tutorial I had to use `isLoadingNext` boolean prop that is returned from `usePaginationFragement` instead. Not sure if this a bug, or by design.

As a beginner, I spent quite some time trying to figure out why my code wasn't working, after a bit of digging I ran into some potenially related issues:
- facebook#4531 (comment)
- facebook#4526
- facebook#3082

In this PR I've updated the "Improving the Loading Experience with useTransition" example not to confuse newcomers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants