Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 5.10.0

- Upgraded `@tanstack/react-query` to `5.83.0`. You might have duplicate versions if you already had it in your dependencies. Should you have an error mentioning the `QueryContext`, make sure you only have one version in your package manager lock file.

## 5.9.1

* Fix `<Datagrid>` empty throws error when used in standalone mode ([#10812](https://github.com/marmelab/react-admin/pull/10812)) ([fzaninotto](https://github.com/fzaninotto))
Expand Down
36 changes: 36 additions & 0 deletions docs/List.md
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,42 @@ const ProductList = () => (
)
```

## Enabling Data Fetching Conditionally
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm not sure about where to put this documentation as it's actually useGetList that we configure.

Copy link
Member

Choose a reason for hiding this comment

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

I think it's fine here 👍


You might want to allow data to be fetched only when at least some filters have been set. You can leverage TanStack react-query `enabled` option for that. It accepts a function that receives the query as its only parameter. As react-admin always format the `queryKey` as `[ResourceName, DataProviderMethod, DataProviderParams]`, you can check that there is at least a filter in this function:

{% raw %}
```tsx
export const PostList = () => (
<List
filters={postFilter}
queryOptions={{
enabled: query => {
const listParams = query.queryKey[2] as GetListParams;
return listParams.filter.q?.length > 2;
}
}}
>
<WithListContext
render={context =>
context.filterValues.q?.length > 2 ? (
<CardContentInner>
Type a search term to fetch data
</CardContentInner>
) : (
<Datagrid>
{/* your fields */}
</Datagrid>
)
}
/>
</List>
)
```
{% endraw %}

**Note**: Notice we display some custom UI when there is no filter. This is because otherwise, users would see the loading UI as Tanstack Query will set the `isPending` property of the underlying query to `true` if the query isn't enabled.

## Accessing Extra Response Data

If `dataProvider.getList()` returns additional metadata in the response under the `meta` key, you can access it in the list view using the `meta` property of the `ListContext`.
Expand Down
4 changes: 2 additions & 2 deletions examples/simple/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
"dependencies": {
"@mui/icons-material": "^5.16.12",
"@mui/material": "^5.16.12",
"@tanstack/react-query": "^5.21.7",
"@tanstack/react-query-devtools": "^5.21.7",
"@tanstack/react-query": "^5.83.0",
"@tanstack/react-query-devtools": "^5.83.0",
"jsonexport": "^3.2.0",
"lodash": "~4.17.5",
"ra-data-fakerest": "^5.9.1",
Expand Down
3 changes: 1 addition & 2 deletions packages/ra-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@
"react-router-dom": "^6.28.1 || ^7.1.1"
},
"dependencies": {
"@tanstack/react-query": "^5.21.7",
"clsx": "^2.1.1",
Copy link
Member

Choose a reason for hiding this comment

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

👍 good catch

"@tanstack/react-query": "^5.83.0",
"date-fns": "^3.6.0",
"eventemitter3": "^5.0.1",
"inflection": "^3.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/ra-core/src/auth/useAuthState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ const useAuthState = <ErrorType = Error>(

return authProvider != null
? result
: (noAuthProviderQueryResult as UseAuthStateResult<ErrorType>);
: (noAuthProviderQueryResult as unknown as UseAuthStateResult<ErrorType>);
};

type UseAuthStateOptions<ErrorType = Error> = Omit<
Expand Down
2 changes: 1 addition & 1 deletion packages/ra-core/src/auth/useCanAccess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export const useCanAccess = <

return authProviderHasCanAccess
? result
: (emptyQueryObserverResult as UseCanAccessResult<ErrorType>);
: (emptyQueryObserverResult as unknown as UseCanAccessResult<ErrorType>);
};

const emptyQueryObserverResult = {
Expand Down
5 changes: 4 additions & 1 deletion packages/ra-core/src/auth/usePermissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,10 @@ const usePermissions = <PermissionsType = any, ErrorType = Error>(
);

return !authProvider || !authProvider.getPermissions
? (fakeQueryResult as UsePermissionsResult<PermissionsType, ErrorType>)
? (fakeQueryResult as unknown as UsePermissionsResult<
PermissionsType,
ErrorType
>)
: result;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ export const useReferenceInputController = <RecordType extends RaRecord = any>(
} = useReference<RecordType>({
id: currentValue,
reference,
// @ts-ignore the types of the queryOptions for the getMAny and getList are not compatible
options: {
// @ts-ignore the types of the queryOptions for the getMAny and getList are not compatible
enabled: currentValue != null && currentValue !== '',
meta,
...otherQueryOptions,
Expand Down
2 changes: 1 addition & 1 deletion packages/ra-core/src/dataProvider/useGetList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export const useGetList = <
}
: result,
[result]
) as UseQueryResult<RecordType[], Error> & {
) as unknown as UseQueryResult<RecordType[], Error> & {
Copy link
Member

Choose a reason for hiding this comment

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

Question: Why do we only need to do that when calling dataProvider.getList() and not for every other usage of useQuery (e.g. useGetOne) ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Because useGetOne returns the same format as react query and we made the decision to do things differently in all hooks that also return a total. Instead of data.total we wanted to have total directly on the result.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

For the record, I'd love to change that in v6

total?: number;
pageInfo?: {
hasNextPage?: boolean;
Expand Down
2 changes: 1 addition & 1 deletion packages/ra-core/src/dataProvider/useGetManyReference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ export const useGetManyReference = <
}
: result,
[result]
) as UseQueryResult<RecordType[], ErrorType> & {
) as unknown as UseQueryResult<RecordType[], ErrorType> & {
total?: number;
pageInfo?: {
hasNextPage?: boolean;
Expand Down
1 change: 0 additions & 1 deletion packages/ra-core/src/dataProvider/useInfiniteGetList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,6 @@ export type UseInfiniteGetListOptions<
GetInfiniteListResult<RecordType>,
ErrorType,
InfiniteData<GetInfiniteListResult<RecordType>>,
GetInfiniteListResult<RecordType>,
Copy link
Member

Choose a reason for hiding this comment

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

does that mean that the type of UseInfiniteQueryOptions has changed in react-query? That would be a breaking change.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No I believe we used it incorrectly before but it wasn't detected until this update

Copy link
Member

Choose a reason for hiding this comment

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

I think it's due to TanStack/query#8956. It doesn't seem to be a breaking change.

QueryKey,
number
>,
Expand Down
2 changes: 1 addition & 1 deletion packages/ra-no-code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"react-dom": "^18.0.0 || ^19.0.0"
},
"dependencies": {
"@tanstack/react-query": "^5.21.7",
"@tanstack/react-query": "^5.83.0",
"clsx": "^2.1.1",
"date-fns": "^3.6.0",
"inflection": "^3.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/ra-ui-materialui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"react-router-dom": "^6.28.1 || ^7.1.1"
},
"dependencies": {
"@tanstack/react-query": "^5.21.7",
"@tanstack/react-query": "^5.83.0",
"autosuggest-highlight": "^3.1.1",
"clsx": "^2.1.1",
"css-mediaquery": "^0.1.2",
Expand Down
48 changes: 46 additions & 2 deletions packages/ra-ui-materialui/src/list/List.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import * as React from 'react';
import { Admin, AutocompleteInput } from 'react-admin';
import { Admin, AutocompleteInput, CardContentInner } from 'react-admin';
import {
CustomRoutes,
Resource,
useListContext,
TestMemoryRouter,
DataProvider,
GetListParams,
WithListContext,
} from 'ra-core';
import fakeRestDataProvider from 'ra-data-fakerest';
import {
Expand Down Expand Up @@ -142,7 +144,10 @@ const data = {
authors: [],
};

const defaultDataProvider = fakeRestDataProvider(data);
const defaultDataProvider = fakeRestDataProvider(
data,
process.env.NODE_ENV !== 'test'
);

const BookList = () => {
const { error, isPending } = useListContext();
Expand Down Expand Up @@ -229,6 +234,45 @@ export const Filters = () => (
</TestMemoryRouter>
);

export const ConditionalDataFetching = () => (
<TestMemoryRouter initialEntries={['/books']}>
<Admin dataProvider={defaultDataProvider}>
<Resource
name="books"
list={() => (
<List
filters={[<SearchInput source="q" alwaysOn />]}
empty={false}
queryOptions={{
enabled: query => {
const params = query
.queryKey[2] as GetListParams;
return (
params.filter.q != null &&
params.filter.q !== ''
);
},
}}
>
<WithListContext
render={context =>
context.filterValues.q == null ||
context.filterValues.q === '' ? (
<CardContentInner>
Type a search term to fetch data
</CardContentInner>
) : (
<BookList />
)
}
/>
</List>
)}
/>
</Admin>
</TestMemoryRouter>
);

export const Filter = () => (
<TestMemoryRouter initialEntries={['/books']}>
<Admin dataProvider={defaultDataProvider}>
Expand Down
1 change: 1 addition & 0 deletions packages/react-admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"@emotion/styled": "^11.14.0",
"@mui/icons-material": "^5.16.12 || ^6.0.0 || ^7.0.0",
"@mui/material": "^5.16.12 || ^6.0.0 || ^7.0.0",
"@tanstack/react-query": "^5.83.0",
"ra-core": "^5.9.1",
"ra-i18n-polyglot": "^5.9.1",
"ra-language-english": "^5.9.1",
Expand Down
52 changes: 26 additions & 26 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4312,40 +4312,40 @@ __metadata:
languageName: node
linkType: hard

"@tanstack/query-core@npm:5.47.0":
version: 5.47.0
resolution: "@tanstack/query-core@npm:5.47.0"
checksum: 2d2378dbde2b0610b6356fcdb56904aa9d41c140c17ceb55e257b918c8555484ff36743a6a37768575631be96b9291eedc53723cd80326783095499cb97db049
"@tanstack/query-core@npm:5.83.0":
version: 5.83.0
resolution: "@tanstack/query-core@npm:5.83.0"
checksum: e6dc480bc99eaca552a9ad65423788b60368cf99308681252fc7dbe42a3f2c1c978db0d3471cc3349b9112cfb4d967ace4e192a1d7e987e30c5c1ff74809c77c
languageName: node
linkType: hard

"@tanstack/query-devtools@npm:5.47.0":
version: 5.47.0
resolution: "@tanstack/query-devtools@npm:5.47.0"
checksum: b6223395794d08f96d57395c0dcdfbc7cc73c311e82f1a7a13b8685ad8f0e4f10b537df46f7e7e4b65bc29f480a915f246937310d650e01d7db915f4c4757ada
"@tanstack/query-devtools@npm:5.81.2":
version: 5.81.2
resolution: "@tanstack/query-devtools@npm:5.81.2"
checksum: f942cba7bd3ecb471063cd472eeebb2ec76005feeb7e0f357b191da5ab9f769aa767bc88d4da82b2b39c4fcbb16dfed38ce3c77b6eea4d4c30405368c1120207
languageName: node
linkType: hard

"@tanstack/react-query-devtools@npm:^5.21.7":
version: 5.47.0
resolution: "@tanstack/react-query-devtools@npm:5.47.0"
"@tanstack/react-query-devtools@npm:^5.83.0":
version: 5.83.0
resolution: "@tanstack/react-query-devtools@npm:5.83.0"
dependencies:
"@tanstack/query-devtools": "npm:5.47.0"
"@tanstack/query-devtools": "npm:5.81.2"
peerDependencies:
"@tanstack/react-query": ^5.47.0
"@tanstack/react-query": ^5.83.0
react: ^18 || ^19
checksum: 1c2a5916b8ac3c580263114c6ff5bf780f655d777ddd1027187f200f6a29703e28be98fadd0918537eb3f07cbfe283013f4212eafa7facde25116ab42b38d4e9
checksum: 9d3c0c4ba5d5f42d1e76a5d009d768fe407e2bcdfa24986236a5b501bf41de8a04c30ebca97c871f822f6c20e508490943dbe0602640770d95f518cce9e7a760
languageName: node
linkType: hard

"@tanstack/react-query@npm:^5.21.7":
version: 5.47.0
resolution: "@tanstack/react-query@npm:5.47.0"
"@tanstack/react-query@npm:^5.83.0":
version: 5.83.0
resolution: "@tanstack/react-query@npm:5.83.0"
dependencies:
"@tanstack/query-core": "npm:5.47.0"
"@tanstack/query-core": "npm:5.83.0"
peerDependencies:
react: ^18.0.0
checksum: ed94c3255fd20180b0d133138f621ab471729c218c926321d316c3565061c7127e6f1f60c5020ef40455c740b8b5a525bd91292a271f63e7315114c810ddff6f
react: ^18 || ^19
checksum: 883229f9219ca906a54d7caafd44d59b57db5dbe87e954f8a7027f460e9f8b97842dfbd0d676dc3111d577baf312c64f6c1fdd67cd1e4b0f0bf574e29670c606
languageName: node
linkType: hard

Expand Down Expand Up @@ -16027,14 +16027,13 @@ __metadata:
resolution: "ra-core@workspace:packages/ra-core"
dependencies:
"@hookform/resolvers": "npm:^3.2.0"
"@tanstack/react-query": "npm:^5.21.7"
"@tanstack/react-query": "npm:^5.83.0"
"@testing-library/react": "npm:^15.0.7"
"@types/jest": "npm:^29.5.2"
"@types/jscodeshift": "npm:^0.11.11"
"@types/node": "npm:^20.10.7"
"@types/node-polyglot": "npm:^0.4.31"
"@types/react": "npm:^18.3.3"
clsx: "npm:^2.1.1"
cross-env: "npm:^5.2.0"
date-fns: "npm:^3.6.0"
echarts: "npm:^5.6.0"
Expand Down Expand Up @@ -16271,7 +16270,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "ra-no-code@workspace:packages/ra-no-code"
dependencies:
"@tanstack/react-query": "npm:^5.21.7"
"@tanstack/react-query": "npm:^5.83.0"
"@testing-library/react": "npm:^15.0.7"
"@testing-library/user-event": "npm:^14.5.2"
clsx: "npm:^2.1.1"
Expand Down Expand Up @@ -16305,7 +16304,7 @@ __metadata:
"@mui/material": "npm:^5.16.12"
"@mui/system": "npm:^5.16.12"
"@mui/utils": "npm:^5.16.12"
"@tanstack/react-query": "npm:^5.21.7"
"@tanstack/react-query": "npm:^5.83.0"
"@testing-library/react": "npm:^15.0.7"
"@types/dompurify": "npm:^3.0.2"
"@types/react": "npm:^18.3.3"
Expand Down Expand Up @@ -16515,6 +16514,7 @@ __metadata:
"@emotion/styled": "npm:^11.14.0"
"@mui/icons-material": "npm:^5.16.12 || ^6.0.0 || ^7.0.0"
"@mui/material": "npm:^5.16.12 || ^6.0.0 || ^7.0.0"
"@tanstack/react-query": "npm:^5.83.0"
cross-env: "npm:^5.2.0"
expect: "npm:^27.4.6"
ra-core: "npm:^5.9.1"
Expand Down Expand Up @@ -17860,8 +17860,8 @@ __metadata:
"@hookform/devtools": "npm:^4.3.3"
"@mui/icons-material": "npm:^5.16.12"
"@mui/material": "npm:^5.16.12"
"@tanstack/react-query": "npm:^5.21.7"
"@tanstack/react-query-devtools": "npm:^5.21.7"
"@tanstack/react-query": "npm:^5.83.0"
"@tanstack/react-query-devtools": "npm:^5.83.0"
"@vitejs/plugin-react": "npm:^4.3.4"
jsonexport: "npm:^3.2.0"
little-state-machine: "npm:^4.8.1"
Expand Down
Loading