Skip to content

Commit

Permalink
feat: remove overloads (#4714)
Browse files Browse the repository at this point in the history
* refactor(query-core): remove overloads

remove overloads and only allow all functions to be called with a single signature

BREAKING CHANGE:  Overloads are removed, query-core now supports a single signature

* test(query-core): apply single signature to all tests

* refactor(react-query): remove overloads

remove overloads and only allow all functions to be called with a single signature

BREAKING CHANGE:  Overloads are removed, react-query now supports a single signature

* test(react-query): apply single signature to all tests

* refactor(solid-query): remove overloads

remove overloads and only allow all functions to be called with a single signature

BREAKING CHANGE:  Overloads are removed, solid-query now supports a single signature

* test(solid-query): apply single signature to all tests

* refactor(vue-query): remove overloads

remove overloads and only allow all functions to be called with a single signature

BREAKING CHANGE:  Overloads are removed, vue-query now supports a single signature

* test(vue-query): apply single signature to all tests

* test(react-query-persist-client): apply single signature to all tests

* fix(react-query-devtools): apply single signature to all tests

* test(react-query-devtools): apply single signature to all tests

* test(query-sync-storage-persister): apply single signature to all tests

* docs: apply object single signature to all docs

* docs(examples/react): apply object single signature to all examples

* docs(examples/solid): apply object single signature to all examples

* docs(examples/vue): apply object single signature to all examples

* style(examples): run prettier on all files

* docs:  use multiline whenever we use the object syntax

* fix(setQueryDefaults): keep it as two arguments

* fix(createMutation): remove unnecessary shallow copy

* fix(vue-query): rename parseArgs functions to unrefArgs

* docs(migrating-to-react-query-5): list all affected functions

* fix(setQueryData): remove as alias

* refactor(getQueryData): getQueryData now supports only queryKey as an argument

BREAKING CHANGE: getQueryData now accepts only queryKey as an argument

* refactor(getQueryState): getQueryState now supports only queryKey as an argument

BREAKING CHANGE: getQueryState now accepts only queryKey as an argument

* test(react-query/useQuery): missing single signature
  • Loading branch information
Mamoanwar97 committed Dec 31, 2022
1 parent af2e27e commit eeec5f7
Show file tree
Hide file tree
Showing 82 changed files with 4,032 additions and 4,850 deletions.
40 changes: 28 additions & 12 deletions docs/react/adapters/solid-query.md
Expand Up @@ -13,7 +13,10 @@ import { Switch, Match, For } from 'solid-js'
const queryClient = new QueryClient()

function Example() {
const query = createQuery(() => ['todos'], fetchTodos)
const query = createQuery({
queryKey: () => ['todos'],
queryFn: fetchTodos
})

return (
<div>
Expand Down Expand Up @@ -69,10 +72,16 @@ Solid Query offers an API similar to React Query, but there are some key differ

```tsx
// ❌ react version
useQuery(["todos", todo], fetchTodos)
useQuery({
queryKey: ["todos", todo],
queryFn: fetchTodos
})

// ✅ solid version
createQuery(() => ["todos", todo()], fetchTodos)
createQuery({
queryKey: () => ["todos", todo()],
queryFn: fetchTodos
})
```

- Suspense works for queries out of the box if you access the query data inside a `<Suspense>` boundary.
Expand All @@ -81,7 +90,11 @@ createQuery(() => ["todos", todo()], fetchTodos)
import { For, Suspense } from 'solid-js'

function Example() {
const query = createQuery(() => ['todos'], fetchTodos)
const query = createQuery({
queryKey: () => ['todos'],
queryFn: fetchTodos
})

return (
<div>
{/* ✅ Will trigger loading fallback, data accessed in a suspense context. */}
Expand Down Expand Up @@ -113,20 +126,21 @@ export default function App() {

function Example() {
// ❌ react version -- supports destructing outside reactive context
// const { isLoading, error, data } = useQuery(['repoData'], () =>
// fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res =>
// const { isLoading, error, data } = useQuery({
// queryKey: ['repoData'], () =>
// queryFn: fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res =>
// res.json()
// )
// )
// })

// ✅ solid version -- does not support destructuring outside reactive context
const query = createQuery(
() => ['repoData'],
() =>
const query = createQuery({
queryKey: () => ['repoData'],
queryFn: () =>
fetch('https://api.github.com/repos/tannerlinsley/react-query').then(
(res) => res.json(),
),
)
})

// ✅ access query properties in JSX reactive context
return (
Expand Down Expand Up @@ -161,7 +175,9 @@ const queryClient = new QueryClient()

function Example() {
const [enabled, setEnabled] = createSignal(false)
const query = createQuery(() => ['todos'], fetchTodos, {
const query = createQuery({
queryKey: () => ['todos'],
queryFn: fetchTodos,
// ❌ passing a signal directly is not reactive
// enabled: enabled(),

Expand Down
5 changes: 4 additions & 1 deletion docs/react/community/liaoliao666-react-query-kit.md
Expand Up @@ -66,7 +66,10 @@ console.log(usePost.getKey(variables)) // ['/posts', { id: 1 }]
export async function getStaticProps() {
const queryClient = new QueryClient()

await queryClient.prefetchQuery(usePost.getKey(variables), usePost.queryFn)
await queryClient.prefetchQuery({
queryKey: usePost.getKey(variables),
queryFn: usePost.queryFn
})

return {
props: {
Expand Down
90 changes: 90 additions & 0 deletions docs/react/guides/migrating-to-react-query-5.md
Expand Up @@ -7,6 +7,96 @@ title: Migrating to TanStack Query v5

v5 is a major version, so there are some breaking changes to be aware of:

### Supports a single signature, one object

useQuery and friends used to have many overloads in TypeScript - different ways how the function can be invoked. Not only this was tough to maintain, type wise, it also required a runtime check to see which type the first and the second parameter, to correctly create options.

now we only support the object format.

```diff
- useQuery(key, fn, options)
+ useQuery({ queryKey, queryFn, ...options })

- useInfiniteQuery(key, fn, options)
+ useInfiniteQuery({ queryKey, queryFn, ...options })

- useMutation(fn, options)
+ useMutation({ mutationFn, ...options })

- useIsFetching(key, filters)
+ useIsFetching({ queryKey, ...filters })

- useIsMutating(key, filters)
+ useIsMutating({ mutationKey, ...filters })
```

```diff
- queryClient.isFetching(key, filters)
+ queryClient.isFetching({ queryKey, ...filters })

- queryClient.ensureQueryData(key, filters)
+ queryClient.ensureQueryData({ queryKey, ...filters })

- queryClient.getQueriesData(key, filters)
+ queryClient.getQueriesData({ queryKey, ...filters })

- queryClient.setQueriesData(key, updater, filters, options)
+ queryClient.setQueriesData({ queryKey, ...filters }, updater, options)

- queryClient.removeQueries(key, filters)
+ queryClient.removeQueries({ queryKey, ...filters })

- queryClient.resetQueries(key, filters, options)
+ queryClient.resetQueries({ queryKey, ...filters }, options)

- queryClient.cancelQueries(key, filters, options)
+ queryClient.cancelQueries({ queryKey, ...filters }, options)

- queryClient.invalidateQueries(key, filters, options)
+ queryClient.invalidateQueries({ queryKey, ...filters }, options)

- queryClient.refetchQueries(key, filters, options)
+ queryClient.refetchQueries({ queryKey, ...filters }, options)

- queryClient.fetchQuery(key, fn, options)
+ queryClient.fetchQuery({ queryKey, queryFn, ...options })

- queryClient.prefetchQuery(key, fn, options)
+ queryClient.prefetchQuery({ queryKey, queryFn, ...options })

- queryClient.fetchInfiniteQuery(key, fn, options)
+ queryClient.fetchInfiniteQuery({ queryKey, queryFn, ...options })

- queryClient.prefetchInfiniteQuery(key, fn, options)
+ queryClient.prefetchInfiniteQuery({ queryKey, queryFn, ...options })
```

```diff
- queryCache.find(key, filters)
+ queryCache.find({ queryKey, ...filters })

- queryCache.findAll(key, filters)
+ queryCache.findAll({ queryKey, ...filters })
```

### `queryClient.getQueryData` now accepts queryKey only as an Argument

`queryClient.getQueryData` argument is changed to accept only a `queryKey`

```diff
- queryClient.getQueryData(queryKey, filters)
+ queryClient.getQueryData(queryKey)
```

### `queryClient.getQueryState` now accepts queryKey only as an Argument

`queryClient.getQueryState` argument is changed to accept only a `queryKey`

```diff
- queryClient.getQueryState(queryKey, filters)
+ queryClient.getQueryState(queryKey)
```

### The `remove` method has been removed from useQuery

Previously, remove method used to remove the query from the queryCache without informing observers about it. It was best used to remove data imperatively that is no longer needed, e.g. when logging a user out.
Expand Down
6 changes: 3 additions & 3 deletions docs/react/reference/QueryClient.md
Expand Up @@ -172,7 +172,7 @@ const data = queryClient.getQueryData(queryKey)

**Options**

- `filters?: QueryFilters`: [Query Filters](../guides/filters#query-filters)
- `queryKey: QueryKey`: [Query Keys](../guides/query-keys)

**Returns**

Expand Down Expand Up @@ -263,13 +263,13 @@ Updates via `setQueryData` must be performed in an _immuatable_ way. **DO NOT**
`getQueryState` is a synchronous function that can be used to get an existing query's state. If the query does not exist, `undefined` will be returned.

```tsx
const state = queryClient.getQueryState({ queryKey })
const state = queryClient.getQueryState(queryKey)
console.log(state.dataUpdatedAt)
```

**Options**

- `filters?: QueryFilters`: [Query Filters](../guides/filters#query-filters)
- `queryKey: QueryKey`: [Query Keys](../guides/query-keys)

## `queryClient.setQueriesData`

Expand Down
40 changes: 28 additions & 12 deletions docs/solid/overview.md
Expand Up @@ -14,7 +14,10 @@ import { Switch, Match, For } from 'solid-js'
const queryClient = new QueryClient()

function Example() {
const query = createQuery(() => ['todos'], fetchTodos)
const query = createQuery({
queryKey: () => ['todos'],
queryFn: fetchTodos
})

return (
<div>
Expand Down Expand Up @@ -70,10 +73,16 @@ Solid Query offers an API similar to React Query, but there are some key differ

```tsx
// ❌ react version
useQuery(["todos", todo], fetchTodos)
useQuery({
queryKey: ["todos", todo],
queryFn: fetchTodos
})

// ✅ solid version
createQuery(() => ["todos", todo()], fetchTodos)
createQuery({
queryKey: () => ["todos", todo()],
queryFn: fetchTodos
})
```

- Suspense works for queries out of the box if you access the query data inside a `<Suspense>` boundary.
Expand All @@ -82,7 +91,11 @@ createQuery(() => ["todos", todo()], fetchTodos)
import { For, Suspense } from 'solid-js'

function Example() {
const query = createQuery(() => ['todos'], fetchTodos)
const query = createQuery({
queryKey: () => ['todos'],
queryFn: fetchTodos
}
)
return (
<div>
{/* ✅ Will trigger loading fallback, data accessed in a suspense context. */}
Expand Down Expand Up @@ -114,20 +127,21 @@ export default function App() {

function Example() {
// ❌ react version -- supports destructing outside reactive context
// const { isLoading, error, data } = useQuery(['repoData'], () =>
// fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res =>
// const { isLoading, error, data } = useQuery({
// queryKey: ['repoData'], () =>
// queryFn: fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res =>
// res.json()
// )
// )
// })

// ✅ solid version -- does not support destructuring outside reactive context
const query = createQuery(
() => ['repoData'],
() =>
const query = createQuery({
queryKey: () => ['repoData'],
queryFn: () =>
fetch('https://api.github.com/repos/tannerlinsley/react-query').then(
(res) => res.json(),
),
)
})

// ✅ access query properties in JSX reactive context
return (
Expand Down Expand Up @@ -162,7 +176,9 @@ const queryClient = new QueryClient()

function Example() {
const [enabled, setEnabled] = createSignal(false)
const query = createQuery(() => ['todos'], fetchTodos, {
const query = createQuery({
queryKey: () => ['todos'],
queryFn: fetchTodos,
// ❌ passing a signal directly is not reactive
// enabled: enabled(),

Expand Down
14 changes: 6 additions & 8 deletions examples/react/load-more-infinite-scroll/pages/index.js
Expand Up @@ -33,17 +33,15 @@ function Example() {
fetchPreviousPage,
hasNextPage,
hasPreviousPage,
} = useInfiniteQuery(
['projects'],
async ({ pageParam = 0 }) => {
} = useInfiniteQuery({
queryKey: ['projects'],
queryFn: async ({ pageParam = 0 }) => {
const res = await axios.get('/api/projects?cursor=' + pageParam)
return res.data
},
{
getPreviousPageParam: (firstPage) => firstPage.previousId ?? undefined,
getNextPageParam: (lastPage) => lastPage.nextId ?? undefined,
},
)
getPreviousPageParam: (firstPage) => firstPage.previousId ?? undefined,
getNextPageParam: (lastPage) => lastPage.nextId ?? undefined,
})

React.useEffect(() => {
if (inView) {
Expand Down
10 changes: 5 additions & 5 deletions examples/react/react-native/src/screens/MovieDetailsScreen.tsx
Expand Up @@ -22,11 +22,11 @@ type Props = {
};

export function MovieDetailsScreen({ route }: Props) {
const { isLoading, error, data, refetch } = useQuery<MovieDetails, Error>(
['movie', route.params.movie.title],
() => fetchMovie(route.params.movie.title),
{ initialData: route.params.movie as MovieDetails }
);
const { isLoading, error, data, refetch } = useQuery<MovieDetails, Error>({
queryKey: ['movie', route.params.movie.title],
queryFn: () => fetchMovie(route.params.movie.title),
initialData: route.params.movie as MovieDetails,
});

const { isRefetchingByUser, refetchByUser } = useRefreshByUser(refetch);

Expand Down
8 changes: 4 additions & 4 deletions examples/react/react-native/src/screens/MoviesListScreen.tsx
Expand Up @@ -22,10 +22,10 @@ type Props = {
};

export function MoviesListScreen({ navigation }: Props) {
const { isLoading, error, data, refetch } = useQuery<Movie[], Error>(
['movies'],
fetchMovies
);
const { isLoading, error, data, refetch } = useQuery<Movie[], Error>({
queryKey: ['movies'],
queryFn: fetchMovies,
});
const { isRefetchingByUser, refetchByUser } = useRefreshByUser(refetch);
useRefreshOnFocus(refetch);

Expand Down
2 changes: 1 addition & 1 deletion examples/react/react-router/src/routes/root.jsx
Expand Up @@ -37,7 +37,7 @@ export const action = (queryClient) => async () => {
export default function Root() {
const { q } = useLoaderData();
const { data: contacts } = useQuery(contactListQuery(q));
const searching = useIsFetching(["contacts", "list"]) > 0;
const searching = useIsFetching({ queryKey: ["contacts", "list"] }) > 0;
const navigation = useNavigation();
const submit = useSubmit();

Expand Down
12 changes: 5 additions & 7 deletions examples/solid/basic-typescript/src/index.tsx
Expand Up @@ -97,13 +97,11 @@ const getPostById = async (id: number): Promise<Post> => {
}

function createPost(postId: number) {
return createQuery(
() => ['post', postId],
() => getPostById(postId),
{
enabled: !!postId,
},
)
return createQuery({
queryKey: () => ['post', postId],
queryFn: () => getPostById(postId),
enabled: !!postId,
})
}

function Post(props: { postId: number; setPostId: Setter<number> }) {
Expand Down

0 comments on commit eeec5f7

Please sign in to comment.