useGetManyReference

This hook calls dataProvider.getManyReference() when the component mounts. It queries the data provider for a list of records related to another one (e.g. all the comments for a post). It supports filtering, sorting, and pagination.

Syntax

const { data, total, isLoading, error, refetch } = useGetManyReference(
    resource,
    { target, id, pagination, sort, filter, meta },
    options
);

Usage

import { useGetManyReference, useRecordContext } from 'react-admin';

const PostComments = () => {
    const record = useRecordContext();
    // fetch all comments related to the current record
    const { data, isLoading, error } = useGetManyReference(
        'comments',
        { 
            target: 'post_id',
            id: record.id,
            pagination: { page: 1, perPage: 10 },
            sort: { field: 'published_at', order: 'DESC' }
        }
    );
    if (isLoading) { return <Loading />; }
    if (error) { return <p>ERROR</p>; }
    return (
        <ul>
            {data.map(comment => (
                <li key={comment.id}>{comment.body}</li>
            ))}
        </ul>
    );
};

Partial Pagination

If your data provider doesn’t return the total number of records (see Partial Pagination), you can use the pageInfo field to determine if there are more records to fetch.

import { useState } from 'react';
import { useGetManyReference, useRecordContext } from 'react-admin';

const PostComments = () => {
    const record = useRecordContext();
    const [page, setPage] = useState(1);
    const { data, isLoading, pageInfo, error } = useGetManyReference(
        'comments',
        { 
            target: 'post_id',
            id: record.id,
            pagination: { page, perPage: 10 },
            sort: { field: 'published_at', order: 'DESC' }
        }
    );
    if (isLoading) { return <Loading />; }
    if (error) { return <p>ERROR</p>; }
    const { hasNextPage, hasPreviousPage } = pageInfo;

    const getNextPage = () => setPage(page + 1);

    return (
        <>
            <ul>
                {data.map(comment => (
                    <li key={comment.id}>{comment.body}</li>
                ))}
            </ul>
            {hasNextPage && <button onClick={getNextPage}>More comments</button>}
        </>
    );
};

TypeScript

The useGetManyReference hook accepts a generic parameter for the record type:

import { useGetManyReference, useRecordContext } from 'react-admin';

type Post = {
    id: number;
    title: string;
};

type Comment = {
    id: number;
    post_id: string;
    body: string;
    published_at: Date;
}

const PostComments = () => {
    const post = useRecordContext<Post>();
    // fetch all comments related to the current record
    const { data: comments, isLoading, error } = useGetManyReference<Comment>(
        'comments',
        { 
            target: 'post_id',
            id: record.id,
            pagination: { page: 1, perPage: 10 },
            sort: { field: 'published_at', order: 'DESC' }
        }
    );
    if (isLoading) { return <Loading />; }
    if (error) { return <p>ERROR</p>; }
    return (
        <ul>
            {/* TypeScript knows that comments is of type Comment[] */}
            {comments.map(comment => (
                <li key={comment.id}>{comment.body}</li>
            ))}
        </ul>
    );
};