Skip to content

V3 Umbrella Issue #772

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

Closed
22 tasks done
tannerlinsley opened this issue Jul 17, 2020 · 41 comments
Closed
22 tasks done

V3 Umbrella Issue #772

tannerlinsley opened this issue Jul 17, 2020 · 41 comments
Labels
documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed v3

Comments

@tannerlinsley
Copy link
Collaborator

tannerlinsley commented Jul 17, 2020

Below are the official breaking changes and features for v3. If you have a feature request or idea, please use the Discussions tab to open a new discussion about that idea.

Global:

  • Remove usePaginatedQuery.
  • Remove ReactQueryConfig.shared as it only contains one value.
  • Change QueryConfig.enabled type to boolean but keep behavior.
  • Change query key type to match with documentation (string | any[]).
  • Remove react-query.mjs in favor of unbundled ESM files.
  • QueryCache and Query async methods should throw and hook methods should not.

Query:

  • Rename clear() to remove().
  • Remove refetch() in favor of QueryObserver.refetch(). The refetch() method on Query is redundant as the functionality is the same as fetch().
  • Remove subscribe() as it is only used in the tests.
  • Remove fetchMoreVariable argument from fetchMore() in favor of FetchMoreOptions.

QueryCache:

  • Remove global query cache.
  • Remove makeQueryCache in favor of new QueryCache().
  • Remove resetErrorBoundaries().
  • Remove prefetch() options (force/throwOnError).
  • Rename prefetchQuery() to fetchQuery().
  • Change isFetching to isFetching() and do not store state.
  • Remove true predicate option from getQueries() in favor of undefined.

ReactQueryCacheProvider

  • Make usage required. (Non-breaking, documented)
  • Do not create query cache automatically.

QueryObserver:

  • Rename clear() to remove(). (Non-breaking deprecation)

Query Config:

  • Remove forceFetchOnMount.
  • Change refetchOnMount false behavior to disable refetch on mount for that specific hook
@tannerlinsley tannerlinsley pinned this issue Jul 17, 2020
@TanStack TanStack locked as resolved and limited conversation to collaborators Jul 17, 2020
@TanStack TanStack unlocked this conversation Jul 17, 2020
@TanStack TanStack locked as resolved and limited conversation to collaborators Jul 17, 2020
@tannerlinsley tannerlinsley added documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed labels Jul 17, 2020
@TanStack TanStack unlocked this conversation Jul 22, 2020
@smashercosmo
Copy link
Contributor

Would be nice to address this somehow in v3 #669

@Danscap
Copy link

Danscap commented Aug 8, 2020

@tannerlinsley is there any support for class components for react? not directly but rendering a functional component with query hooks into a class component.

@kamranayub
Copy link
Contributor

For V3, I'd propose allowing extending the QueryCache class when calling makeQueryCache (or providing a custom cache).

Use case: I am writing test utilities that allow you to mock named queries and right now the QueryCache methods for getting/setting only work with exact query key matches but when testing, we want to support partial matching.

To handle this, I have to mutate the queryCache that comes back to override methods when it would be nicer to extend QueryCache instead.

class TestQueryCache extends QueryCache {
 // override member methods as-needed
}

const testQueryCache = makeQueryCache(TestQueryCache);
// or queryCaches.push(testQueryCache) could also probably work
// but this leaks implementation details

At the crux of this I am looking for a way to intercept cache gets and sets, so any way to accomplish the same thing would work as well. 👍

@todortotev
Copy link
Contributor

@tannerlinsley
If there is something I can help with I would be glad to assist.

@boschni
Copy link
Collaborator

boschni commented Sep 15, 2020

@kamranayub in the latest version the QueryCache class is exported and can be used to instantiate a query cache

@timkindberg
Copy link

Aw bummer I like how the global queryCache does not use Context. How will we access the queryCache in our custom hooks then? Or set the queryCache programmatically for fetch-as-you-render? Also I'm working on a lib that behaves like Zustand (global state) but uses regular hooks. I was excited by the prospect of being able to actually use the two libs together elegantly instead of just using them side-by-side.

@timkindberg
Copy link

Would there be any interest in allowing a zustand-like selector to subscribe to only a selected portion of the query's data? That way components could have granular control of re-renders.

Something like this:

// All data
const { data: { count, items, limit, offset} , isLoading, isSuccess, } = useQuery('items', () => fetch('/api/items'))

// Just the count
const { data: count, isLoading, isSuccess, } = useQuery('items', () => fetch('/api/items'), { select: s => s.count })

@timkindberg
Copy link

Would there be any interest in allowing a zustand-like selector...

Oh looks like this may be something that could happen: #883 (comment)

@tannerlinsley
Copy link
Collaborator Author

@timkindberg, the const queryCache = new QueryCache() that you make can still be a singleton, just like the currently exported queryCache global, and thus shouldn't change anything about how you can imperatively interact with the queryCache. It will just be import queryQuery from '../myQueryCache' instead of import { queryCache } from 'react-query'.

Yes we have discussed selectors a bit. We'll have to see how that conversation progresses.

@boschni
Copy link
Collaborator

boschni commented Sep 17, 2020

@timkindberg best way to access a query cache in custom hooks is with useQueryCache.

@pdevito3
Copy link

pdevito3 commented Sep 19, 2020

Are there any particular recommendations that we should know about to use in place of usePaginatedQuery, or is it just as simple as start replacing it with useQuery and call it a day? Only other thing that comes to mind immediately is to do a prefetch for any pages with direct links on the screen.

@ShadyMohammed
Copy link

Can we address #991 in V3?

@mrlubos
Copy link

mrlubos commented Sep 22, 2020

Hi @tannerlinsley, is there any more context around these todo items? Particularly, I'd be interested to know why Remove usePaginatedQuery made it to this list. Thank you!

@razh
Copy link
Contributor

razh commented Sep 22, 2020

usePaginatedQuery can be replaced with a config option on useQuery. That's actually how it's implemented now (keepPreviousData):

https://github.com/tannerlinsley/react-query/blob/e200c99496b7ebea84da5a0df38242d80554a844/src/react/usePaginatedQuery.ts#L62-L70

@mrlubos
Copy link

mrlubos commented Sep 22, 2020

Thank you @razh!

@jaekwak02
Copy link

jaekwak02 commented Oct 1, 2020

  • Change isFetching to isFetching() and do not store state

I documented an unnecessary render that is happening when the query first mounts and can theoretically know that it needs to rerender to set isFetching from false to true, since the cache is stale. You can see it in action in the sandbox below. Will this change solve this (minor) problem?

https://codesandbox.io/s/currying-dust-dom4u?file=/src/App.js

Edit: Maybe I misunderstood this change because it's under the QueryCache and not the Query section, but I am still curious about whether the above issue can be solved.

@boschni
Copy link
Collaborator

boschni commented Oct 1, 2020

I forked your sandbox with V3 and it seems to resolve the issue: https://codesandbox.io/s/kind-cookies-6l56e

@tannerlinsley tannerlinsley unpinned this issue Oct 4, 2020
@tannerlinsley tannerlinsley pinned this issue Oct 4, 2020
@mwmcode
Copy link

mwmcode commented Oct 6, 2020

How can I test v3? As per Tanner's tweet npm install react-query@beta should do it but it's pulling v2.24.0 instead (which matches what's published on npm)

@nghiepdev
Copy link

I'm using Next.js and try to upgrade v2.24.0, cacheTime: Infinity doesn't seem to work properly.

MyApp.getInitialProps = async () => {
  await client.prefetchQuery(
          'posts',
          () => {
            // return fetch()
          },
          {
            cacheTime: Infinity,
          },
   );
}

Some where

const posts = client.getQueryData('posts');

@boschni
Copy link
Collaborator

boschni commented Oct 6, 2020

Hi @nghiepit! Can you provide some more code and create an issue?

@nghiepdev
Copy link

@boschni new #1140 issue created

@ibratoev
Copy link

ibratoev commented Oct 7, 2020

It seems 2.40+ releases are already targeting the v3 changes. Consider fixing the release versions to avoid confusing people.
The breaking change that hit me was the removal of the default cache.

@tannerlinsley
Copy link
Collaborator Author

We’re aware. Working on a fix. At least they’re on the beta channel. If you’d like to submit a PR to help fix it, feel free.

@Filipeue
Copy link

Filipeue commented Oct 8, 2020

Just an idea:
Have you ever considered (optionally, if configured so) to use browser cache as a cache for react-query? It would enable out-of-the-box PWA support. As much as I like the idea to use service worker for caching static resources, it would be nice to use single caching approach for data queries. It may enable instant reload of CSR (client side rendered) SPAs as long as data and resources are in cache.

@talolard
Copy link

talolard commented Oct 9, 2020

Just an idea:
Have you ever considered (optionally, if configured so) to use browser cache as a cache for react-query? It would enable out-of-the-box PWA support. As much as I like the idea to use service worker for caching static resources, it would be nice to use single caching approach for data queries. It may enable instant reload of CSR (client side rendered) SPAs as long as data and resources are in cache.

We did this in our App and I would suggest avoiding it. Different browsers / user settings impose different limits on what and how much can be stored on the browser. Hitting those limits would cause exceptions at best and subtle unexpected behavior at worse

@greggb
Copy link

greggb commented Oct 13, 2020

Looks like v3 is going to be about 10k(minified) larger than v2 according to https://bundlephobia.com/[email protected]

With gzip I realize it's only an extra 1kb, but it's still a hit to low-end mobile when keeping bundle size low is becoming harder. Is there a size target y'all are aiming for?

@tannerlinsley
Copy link
Collaborator Author

@greggb, we're always trying to keep good tabs on the size, since that's one of it's features when compared with apollo and other similar libraries. Even with the addition of the parsed 10kb, we're still well under what most other libraries are. For the future, if and when bundle size takes a giant leap, we're fully prepared to break out the library into separate bundles (much like the hydration api is now) and let users only import what they need.

@greggb
Copy link

greggb commented Oct 13, 2020

@tannerlinsley Thanks Tanner. Reassuring to hear it's a priority for the library. 🤗

@boschni
Copy link
Collaborator

boschni commented Oct 13, 2020

Good point @greggb, there are some ways to mitigate this though. Created a proposal here: #1164

@Thisen
Copy link

Thisen commented Oct 14, 2020

If you need any help with the v3 work, I'd enjoy to contribute - I would just need a little guidance on where to start. 😄

@Filipeue
Copy link

Imagine you have REST API client instances, you use to make requests, but in tests (or during development if API is not yet implemented...) you want to replace all clients with fake ones.
I would use react context for the use case but it would be nice to have something built in.
My proposal is:
It would be nice to have option to supply wrapper for every queryFn, configured at startup when creating QueryCache. The wrapper function can then supply additional arguments to queryFn.
There is option to provide default queryFn, but the use case I am looking for is not the same.

@otaciliolacerda
Copy link
Contributor

Imagine you have REST API client instances, you use to make requests, but in tests (or during development if API is not yet implemented...) you want to replace all clients with fake ones.
I would use react context for the use case but it would be nice to have something built in.
My proposal is:
It would be nice to have option to supply wrapper for every queryFn, configured at startup when creating QueryCache. The wrapper function can then supply additional arguments to queryFn.
There is option to provide default queryFn, but the use case I am looking for is not the same.

In my project I use msw to mock the whole API. It is useful to use in the test and also for prototyping when running in dev. There is the advantage of avoiding mocking any implementation in your code. This can be an option.

@Filipeue
Copy link

Imagine you have REST API client instances, you use to make requests, but in tests (or during development if API is not yet implemented...) you want to replace all clients with fake ones.
I would use react context for the use case but it would be nice to have something built in.
My proposal is:
It would be nice to have option to supply wrapper for every queryFn, configured at startup when creating QueryCache. The wrapper function can then supply additional arguments to queryFn.
There is option to provide default queryFn, but the use case I am looking for is not the same.

In my project I use msw to mock the whole API. It is useful to use in the test and also for prototyping when running in dev. There is the advantage of avoiding mocking any implementation in your code. This can be an option.

Nice one, but there are other use cases where mocking solution of this sort is not sufficient. As I was going through API reference It came to me I can use queryFnParamsFilter to add extra argument (service container) to my queryFns. This is what I was looking for even thou it seems weird to add something in function called like that.

@kamranayub
Copy link
Contributor

@timkindberg re: selectors. 👍 We have a wrapper factory we wrote for our lib-specific query implementation that actually uses Reselect so we actually hide data from react-query and instead return a select function:

import { useCurrentUser, selectAddress } from '@data/users';

const { select } = useCurrentUser();
const address = select(selectAddress);

I like the idea of this being built-in to react-query (or as an extension) because when you use a selector ideally you'd only want the hook to cause a re-render if that selected data has changed whereas right now it'll change when data changes.

@tannerlinsley tannerlinsley unpinned this issue Nov 3, 2020
@tannerlinsley tannerlinsley pinned this issue Nov 3, 2020
@Filipeue
Copy link

Filipeue commented Nov 3, 2020

all points seem to be checked, any planned date for official v3 release?

@dougmacklin
Copy link

Hi there 👋, I'm wondering if it would make sense to allow the QueryFunction type to accept a second argument to enable typing the QueryFunctionContext, and in turn allow QueryFunctionContext to accept a second argument to enable typing its queryKey.

Take an example like the one from the Query Function Variables doc:

 function Todos({ completed }) {
   const result = useQuery(['todos', { status, page }], fetchTodoList)
 }
 
 function fetchTodoList({ queryKey }) {
   const { status, page } = queryKey[1]
   return new Promise()
 }

In typescript I would define fetchTodoList as something like:

const fetchTodoList: QueryFunction<TodoListResponse> = ({ queryKey }) => { // ... }

However, accessing the variables with const { status, page } = queryKey[1] results in a type error.

I wish I could do something like this:

const fetchTodoList: QueryFunction<TodoListResponse, QueryFunctionContext<{status: string, page: number}>>

Does that make sense, or am I missing another way around this? Thanks for the great repo!

@boschni
Copy link
Collaborator

boschni commented Nov 9, 2020

Hi @dougmacklin! Inline query functions are preferred, but I added the possibility to type the query key

@dougmacklin
Copy link

Wow thanks for the quick addition @boschni!

When you say "inline function are preferred", do you mean it would be better to just do something like:

const result = useQuery(['todos', { status, page }], () => request(`/api/todos?status=${status}&page=${page}`))

and avoid extracting the query key altogether?

@boschni
Copy link
Collaborator

boschni commented Nov 9, 2020

Np! Yeah either like that or create a function like fetchTodos(status, page) => request(...) and use that one instead of calling request directly but that is up to you :)

@matamatanot
Copy link

Is v3 better for new users?
Most of the problems seem to have been resolved, but when will it be officially released?

@Guria
Copy link

Guria commented Nov 30, 2020

I have completely broken typing with v3 and can't get why. Eg, useQuery return value is infered as any and I don't recieve proper suggerstions for arguments. Ctrl+click on use query still shows some types in d.ts but can' get why it isn't applied.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed v3
Projects
None yet
Development

No branches or pull requests