ReferenceField

Fetches and displays a single referenced record (foreign key lookup). Useful for displaying many-to-one and one-to-one relationships, e.g. the details of a user when rendering a post authored by that user.

Installation

pnpm dlx shadcn@latest add @shadmin/reference-field

Usage

For instance, let's consider a model where a post has one author from the users resource, referenced by a user_id field.

┌──────────────┐       ┌────────────────┐
│ posts        │       │ users          │
│--------------│       │----------------│
│ id           │   ┌───│ id             │
│ user_id      │╾──┘   │ name           │
│ title        │       │ date_of_birth  │
│ published_at │       └────────────────┘
└──────────────┘

In that case, use <ReferenceField> to display the post author's as follows:

import { Show, ReferenceField, TextField, DateField } from "@/components/admin";
 
export const PostShow = () => (
  <Show>
    <div className="flex flex-col gap-4">
      <TextField source="id" />
      <TextField source="title" />
      <DateField source="published_at" />
      <ReferenceField source="user_id" reference="users" label="Author" />
    </div>
  </Show>
);

This component fetches a referenced record (users in this example) using the dataProvider.getMany() method, and renders the recordRepresentation (the record id field by default) wrapped in a link to the related user <Edit> page.

Props

PropRequiredTypeDefaultDescription
sourceRequiredstring-Foreign key in current record
referenceRequiredstring-Target resource name
childrenOptionalReactNode<span> representationCustom child (can use context hooks)
emptyOptionalReactNode-Placeholder when no id / value
errorOptionalReactNode-Error element (set false to hide)
linkOptionalLinkToTypeeditLink target or false / function
loadingOptionalReactNode-Element while loading (set false to hide)
queryOptionsOptionalUseQueryOptions-TanStack Query options (meta, staleTime, etc.)
recordOptionalobjectContext recordExplicit record
renderOptional(ctx)=>ReactNode-Custom renderer receiving reference field context
offlineOptionalReactNode<Offline />Element rendered when the network is offline
translateChoiceOptionalboolean | (record)=>stringtrueTranslate referenced record representation

Record Representation

By default, <ReferenceField> renders the recordRepresentation of the related record.

So it's a good idea to configure the <Resource recordRepresentation> to render related records in a meaningful way. For instance, for the users resource, if you want the <ReferenceField> to display the full name of the author:

<Resource
  name="users"
  list={UserList}
  recordRepresentation={(record) => `${record.first_name} ${record.last_name}`}
/>

If you pass a child component, <ReferenceField> will render it instead of the recordRepresentation. Usual child components for <ReferenceField> are other <Field> components (e.g. <TextField>).

<ReferenceField source="user_id" reference="users">
  <TextField source="name" />
</ReferenceField>

Alternatively to children, pass a render prop. It will receive the ReferenceFieldContext as its argument, and should return a React node.

This allows to inline the render logic for the list of related records.

<ReferenceField
  source="user_id"
  reference="users"
  render={({ error, isPending, referenceRecord }) => {
    if (isPending) {
      return <p>Loading...</p>;
    }
    if (error) {
      return <p className="error">{error.message}</p>;
    }
    return <p>{referenceRecord.name}</p>;
  }}
/>

offline

Element rendered when the network is offline and the reference data is unavailable. Defaults to the inherited offline component from ra-core.

<ReferenceField
  source="author_id"
  reference="authors"
  offline={<span>Offline — author unavailable</span>}
/>

Tips

  • Use link={false} to disable navigation.
  • <ReferenceField> uses dataProvider.getMany() instead of dataProvider.getOne() for performance reasons. When using several <ReferenceField> in the same page (e.g. in a <DataTable>), this allows to call the dataProvider once instead of once per row.