Skip to content

fix: change from onUnmount to onScopeDispose hook #179

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

Merged
merged 5 commits into from
May 4, 2022

Conversation

TomasDurica
Copy link
Contributor

Replacing onUnmounted with onScopeDispose hook will allow better integration and composability with 3rd party libraries that are creating a custom effect scope, that is not tied to the component lifetime (e.g. Pinia)

If you need more info, let me know - or check out the docs

I've marked this change as a fix, as this should be perfectly backwards compatible. Let me know if we also need to include a special test or sample for this functionality, and how would you want it to look like.

@vercel
Copy link

vercel bot commented Apr 24, 2022

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/damianosipiuk/vue-query/8czX4Do5Gr1Y66PUvzrFPvBLbweK
✅ Preview: https://vue-query-git-fork-tomasdurica-main-damianosipiuk.vercel.app

@codesandbox-ci
Copy link

codesandbox-ci bot commented Apr 24, 2022

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit a54a999:

Sandbox Source
DamianOsipiuk/vue-query Configuration
DamianOsipiuk/vue-query: 2.x-basic Configuration
DamianOsipiuk/vue-query: nuxt-simple Configuration

@codecov
Copy link

codecov bot commented Apr 25, 2022

Codecov Report

Merging #179 (a54a999) into main (adce06a) will not change coverage.
The diff coverage is 100.00%.

@@            Coverage Diff            @@
##              main      #179   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           17        17           
  Lines          405       405           
  Branches        67        67           
=========================================
  Hits           405       405           
Impacted Files Coverage Δ
src/vue/useBaseQuery.ts 100.00% <100.00%> (ø)
src/vue/useIsFetching.ts 100.00% <100.00%> (ø)
src/vue/useIsMutating.ts 100.00% <100.00%> (ø)
src/vue/useMutation.ts 100.00% <100.00%> (ø)
src/vue/useQueries.ts 100.00% <100.00%> (ø)
src/vue/useQueryProvider.ts 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update adce06a...a54a999. Read the comment docs.

@DamianOsipiuk
Copy link
Owner

DamianOsipiuk commented Apr 25, 2022

This seems to fail with nuxt2 - codesandbox.io/s/damianosipiuk-vue-query-jwysrg

@TomasDurica
Copy link
Contributor Author

TomasDurica commented Apr 25, 2022

@DamianOsipiuk Hello again - oops, Aprat from the test suite, I've only tested the basic example - Good catch :)

I've fixed the issues - hopefully :) .
I was able to run the nuxt2 exmaple you've provided when targetting the latest commit.

Also I've rolled back some changes that are not that important to reduce some overhead.

I've also illustrated the issue here The posts are reactive unless you hide/show them again, then they lose the reactivity (due to unmounted hook being called when they are hidden)
You cam switch the import to target this PR's version to see the difference

@DamianOsipiuk
Copy link
Owner

DamianOsipiuk commented Apr 25, 2022

Hmm i think there are few things to notice

  • scope dispose work with vue2, but not with nuxt2 (nuxt2 composition API is lacking some features?). So detecting Vue version should be good enought.
  • you do not need pinia to use vue-query. Your state will be shared between components and requests deduplicated without additional boilerplate, just use useQuery. Pinia can still be used for global state. This is due to vue-query having its own state cache. Basically replacing your vuex or pinia boilerplate with vue-query should save you more KBs than vue-query size.
  • this change might still be useful

@TomasDurica
Copy link
Contributor Author

TomasDurica commented Apr 25, 2022

Good point with vue2 - I was investigating further and it seems the problem with not finding the onScopeDispose hook lies
here which was integrated in version 1.1.2. I've bumped the versions, and reverted some code to use the onScopeDispose exclusively, to not pollute the code unnecessarily.

Regarding the points mentioned later, I really appreciate the explanation.
I am aware that my example haven't actually described the reason why I am solving the issue with a centralized store for the sake of simplicity, but if interested, I'm very happy to share the problem and reasoning behind my will to use it like this.

I see vue-query (as well as react-query for that matter) to be a "reactive proxy of a remote state" - even though I am ware that you can use any fetcher, sync or async.
The pinia or any other store implementation, tries to achieve a centralized single source of truth for an application state with an ability for a nice API (with computed properties and actions).
So, in my head, these two are solving different concerns (even-though, vue-query can make a lot of store-centric code obsolete), I am more interested in the behavior and the single-shared state which can "drive the queries".

If I need to have a single app-wide accessible state, using a store like pinia is a no-brainer, as it is pretty lightweight and provides an excellent dev-tools experience (as opposed of exposing home-brewed state, or using a custom injectable context)

Similarly, for async state, vue-query came as a huge thing (I've used with react-query before), especially with the dev tools as well.

Now for the example - it is kinda long, so tl;dr; I have a special case that would benefit from using vue-query within the store:
Imagine that I have a single state, that I want to be able to access through the whole app (to avoid prop drilling, etc...), that consists of multiple queries driven by a user input. some queries are dependent, some not, but in the end, all results are mapped into multiple getters (computed properties), where some of them requires results from multiple queries. This store also provides couple of behaviors that can invalidate multiple queries, and contain some business logic, Currently I am solving this issues by splitting it into the shared sync state (only user inputted values in my case) which are in a store and a lot of custom hooks that are doing the "magic" - some of them are the aforementioned getters, some of them contain the business and mutation logic.
Other, similar solution, would be to have one wrapping function, which would essentially give me the same interface as I am expecting from the store.
These solutions, however, have a couple of issues:

  • It's a bit harder to find and reason about the actual state, as now it is split between vue-query, custom hooks (without dev tools insight), pinia and individual components - you see this can get overwhelming quickly
  • when I combine the results of a number of queries, the resulting computed state can get a little too big and can cause performance issues when used in a huge number of components (while the vue-query results are coming from the cache, the projections are always recreated).

You see, how both of these issues can be easily solved by embedding the queries in the store itself.
I am also aware that I can actually do multiple requests and the projections in the fetcher, and let the cache address the "performance" issues, but, then I would not be able to use vue-query for the individual queries - unless I will do some custom work with the query client.

Anyway, I am really thankful that you are considering this suggestion, and feel free to ask anything, or suggest a different setup.

@vercel
Copy link

vercel bot commented May 4, 2022

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated
vue-query ✅ Ready (Inspect) Visit Preview May 4, 2022 at 7:43AM (UTC)

@sonarqubecloud
Copy link

sonarqubecloud bot commented May 4, 2022

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

@DamianOsipiuk
Copy link
Owner

Hi, sorry for the delay 🙄
Thanks for the contribution 🎉

@DamianOsipiuk DamianOsipiuk merged commit d6eff96 into DamianOsipiuk:main May 4, 2022
@TomasDurica
Copy link
Contributor Author

No worries, I understand that this is an open source project and our time is limited. Thank you as well - if you find any issues - let me know :)

@github-actions
Copy link

github-actions bot commented May 4, 2022

🎉 This PR is included in version 1.23.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants