From 127bbb8edc791dff5561572e8d0651fb7eb9d924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Zaninotto?= Date: Mon, 23 May 2022 10:40:34 +0200 Subject: [PATCH] [Doc] Fix useGetOne section about query aggregation --- docs/useGetOne.md | 84 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 77 insertions(+), 7 deletions(-) diff --git a/docs/useGetOne.md b/docs/useGetOne.md index 7172b4d60fd..8d112b95eba 100644 --- a/docs/useGetOne.md +++ b/docs/useGetOne.md @@ -7,28 +7,98 @@ title: "useGetOne" This hook calls `dataProvider.getOne()` when the component mounts. It queries the data provider for a single record, based on its `id`. +## Syntax + ```jsx -// syntax const { data, isLoading, error, refetch } = useGetOne( resource, { id, meta }, options ); +``` + +The `meta` argument is optional. It can be anything you want to pass to the data provider, e.g. a list of fields to show in the result. + +The `options` parameter is optional, and is passed to [react-query's `useQuery` hook](https://react-query.tanstack.com/reference/useQuery). It may contain the following options: + +* `cacheTime` +* `enabled` +* `initialData` +* `initialDataUpdatedAt` +* `isDataEqual` +* `keepPreviousData` +* `meta` +* `notifyOnChangeProps` +* `notifyOnChangePropsExclusions` +* `onError` +* `onSettled` +* `onSuccess` +* `placeholderData` +* `queryKeyHashFn` +* `refetchInterval` +* `refetchIntervalInBackground` +* `refetchOnMount` +* `refetchOnReconnect` +* `refetchOnWindowFocus` +* `retry` +* `retryOnMount` +* `retryDelay` +* `select` +* `staleTime` +* `structuralSharing` +* `suspense` +* `useErrorBoundary` + +Check [react-query's `useQuery` hook documentation](https://react-query.tanstack.com/reference/useQuery) for details on each of these options. + +The react-query [query key](https://react-query.tanstack.com/guides/query-keys) for this hook is `[resource, 'getOne', { id: String(id), meta }]`. -// example +## Usage + +Call `useGetOne` in a component to query the data provider for a single record, based on its `id`. + +```jsx import { useGetOne } from 'react-admin'; const UserProfile = ({ record }) => { - const { data, isLoading, error } = useGetOne('users', { id: record.id }); + const { data: user, isLoading, error } = useGetOne('users', { id: record.userId }); if (isLoading) { return ; } if (error) { return

ERROR

; } - return
User {data.username}
; + return
User {user.username}
; +}; +``` + +## Aggregating `getOne` Calls + +If you use `useGetOne` several times on a page for the same resource, replace the `useGetOne` call by `useGetManyAggregate`, as it de-duplicates and aggregates queries for a single record into one batch query for many records. + +```diff +-import { useGetOne } from 'react-admin'; ++import { useGetManyAggregate } from 'react-admin'; + +const UserProfile = ({ record }) => { +- const { data: user, isLoading, error } = useGetOne('users', { id: record.userId }); ++ const { data: users, isLoading, error } = useGetManyAggregate('users', { ids: [record.userId] }); + if (isLoading) { return ; } + if (error) { return

ERROR

; } +- return
User {user.username}
; ++ return
User {users[0].username}
; }; ``` -**Tip**: If you use `useGetOne` several times on a page for the same resource, prefer [`useGetMany`](./useGetMany.md) instead, as it de-duplicates and aggregates queries for a single record into one batch query for many records. +This results in less calls to the dataProvider. For instance, if the `` component above is rendered in a ``, it will only make one call to `dataProvider.getMany()` for the entire list instead of one call to `dataProvider.getOne()` per row. + +As this hook is often used to fetch references, react-admin exposes a `useReference` hook, which avoids doing the array conversion manually. It's an application hook rather than a data provider hook, so its syntax is a bit different. Prefer `useReference` to `useGetManyAggregate` when you use `useGetOne` to fetch a reference. ```diff --useGetOne('posts', { id }); -+useGetMany('posts', { id: [id] }); +-import { useGetOne } from 'react-admin'; ++import { useReference } from 'react-admin'; + +const UserProfile = ({ record }) => { +- const { data: user, isLoading, error } = useGetOne('users', { id: record.id }); ++ const { referenceRecord: user, isLoading, error } = useReference({ reference: 'users', id: [record.id] }); + if (isLoading) { return ; } + if (error) { return

ERROR

; } + return
User {data.username}
; +}; ```