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

Ensure refetch, fetchMore, and subscribeToMore functions returned by useSuspenseQuery are referentially stable between renders #10656

Merged
merged 4 commits into from
Mar 17, 2023

Conversation

jerelmiller
Copy link
Member

Currently, the refetch, fetchMore, and subscribeToMore functions exported by useSuspenseQuery are recreated anytime data has changed, causing a rerender. If you were using these functions in useEffect, for example, this could cause that effect to run each time data was updated.

Here is an example taken from the Spotify showcase that demonstrates loading playback state and using a subscription to subscribe to updates to it (with slight variation):

const { data, subscribeToMore } = useSuspenseQuery(PLAYBACK_STATE_QUERY);

useEffect(() => {
  const unsubscribe = subscribeToMore({ 
    document,
    updateQuery: (prev, { subscriptionData }) => { 
      // Update the cache...
    })
  })

  return () => unsubscribe();
}, [subscribeToMore]) // <-- To follow best practice, list subscribeToMore as a dependency

The subscription is fired each time playback state changes on the server, for example the current track's progress. This can happen as often as once a second. Because subscribeToMore is recreated anytime data changes, this meant the effect would re-run every second, constantly toggling between unsubscribing from the subscription and resubscribing.


These functions only rely on the observable as part of its implementation, therefore the recreation of the function was unnecessary. This PR ensures these functions are only recreated anytime the observable changes to ensure they remain referentially stable between renders, even when data is updated.

Checklist:

  • If this PR contains changes to the library itself (not necessary for e.g. docs updates), please include a changeset (see CONTRIBUTING.md)
  • If this PR is a new feature, please reference an issue where a consensus about the design was reached (not necessary for small changes)
  • Make sure all of the significant new logic is covered by tests

@changeset-bot
Copy link

changeset-bot bot commented Mar 15, 2023

🦋 Changeset detected

Latest commit: 8f2e70a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@apollo/client Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Contributor

@alessbell alessbell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙌

@jerelmiller jerelmiller merged commit 54c4d2f into release-3.8 Mar 17, 2023
@jerelmiller jerelmiller deleted the more-usesuspensequery-updates branch March 17, 2023 18:11
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 17, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants