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

(react) - New MutableSource-like hooks implementation for suspense/concurrent #1335

Merged
merged 13 commits into from
Jan 26, 2021

Conversation

kitten
Copy link
Member

@kitten kitten commented Jan 22, 2021

Resolve #1332
Resolve #1272
Resolve #1243 (Won't fix, but this stabilises the issue predictably)

Summary

This swaps out the useQuery implementation for a MutableSource-like implementation, which has been proven to work by valtio (See: https://github.com/pmndrs/valtio/blob/ee4fee75da2054ddfef4cec826c0b9f2e95db4e9/src/useMutableSource.ts)

In this implementation the general behaviour of useQuery does not change and preserves the logic as layed out by our previous useSource implementation. The hook will first start a temporary subscription to client.executeQuery which it'll discard after the mounting process completes. This is facilitated by a call to getSnapshot which handles the suspense cache and throwing suspense promises.

Additionally, if the hook uses suspense-mode this function may throw a suspense promise instead of returning a result. This function is used in the useState initialiser. The state, besides the currently used source, the source's state (the result output), and getSnapshot function, also stores a list of dependencies. This list is compared to the state on every render. If it changes this signifies that the current source should be swapped out and that the state should again be initialised using getSnapshot.

Additionally the results of sources is stored in a "Suspense cache" which is an ad-hoc cache layer that is instantiated by getCacheForClient. This imitates a primitive version of React's upcoming getCacheForType function without any support for splitting the state or keeping it consistent across lanes, as the state is global.
Instead we facilitate Concurrent Mode support by ensuring that all changes in the functionality of the hook work using state changes, which allow React to branch off lanes on any state change.

This is different from our previous useSource hook which kept closure state and effects across suspense triggers and lanes, which causes state to go out of sync.

The suspense cache also protects itself from going stale. Each result in useQuery will update the stored state value in the cache. Additionally we can clear the result from the cache when the client tears down a query. This is done by tracking disposed querieson unmounts. Each time a result in the cache is updated a "dispose claim" for this operation is cleared. Each time a useQuery hook unsubscribes in useEffect it creates a "dispose claim". When the Client sends a teardown operation and a "dispose claim" exists then the cache is cleared of the stale result.
This effectively prevents cached values from being cleared inbetween a mount and the first effect run.

Set of changes

  • Delete useSource
  • Reimplement useQuery with MutableSource-like logic, only branch on state
  • Reimplement useSubscription without useSource similarly
  • Implement getCacheForClient

@changeset-bot
Copy link

changeset-bot bot commented Jan 22, 2021

🦋 Changeset detected

Latest commit: 46cbdf4

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

This PR includes changesets to release 1 package
Name Type
urql Minor

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

JoviDeCroock
JoviDeCroock previously approved these changes Jan 22, 2021
@kitten kitten changed the title WIP: (react) - New Suspense implementation (react) - New MutableSource-like hooks implementation for suspense/concurrent Jan 25, 2021
@kitten kitten marked this pull request as ready for review January 25, 2021 15:22
@kitten kitten merged commit e9962bd into main Jan 26, 2021
@kitten kitten deleted the refactor/new-suspense-impl branch January 26, 2021 16:32
@github-actions github-actions bot mentioned this pull request Jan 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants