Skip to content

<ReferenceOneFieldBase>

This field fetches a one-to-one relationship, e.g. the details of a book, when using a foreign key on the distant resource.

┌──────────────┐ ┌──────────────┐
│ books │ │ book_details │
│--------------│ │--------------│
│ id │───┐ │ id │
│ title │ └──╼│ book_id │
│ published_at │ │ genre │
└──────────────┘ │ ISBN │
└──────────────┘

<ReferenceOneFieldBase> behaves like <ReferenceManyFieldBase>: it uses the current record (a book in this example) to build a filter for the book details with the foreign key (book_id). Then, it uses dataProvider.getManyReference('book_details', { target: 'book_id', id: book.id }) to fetch the related details, and takes the first one.

<ReferenceOneFieldBase> is a headless component, handling only the logic and relying on its children or render prop to render the UI.

Tip: For the inverse relationships (the book linked to a book_detail), you can use a <ReferenceFieldBase>.

Here is how to render a field of the book_details resource inside a Show view for the books resource:

import { ShowBase, ReferenceOneFieldBase, useReferenceFieldContext } from 'ra-core';
const BookShow = () => (
<ShowBase>
<ReferenceOneFieldBase reference="book_details" target="book_id">
<BookDetails />
</ReferenceOneFieldBase>
</ShowBase>
);
const BookDetails = () => {
const context = useReferenceFieldContext({
reference,
target,
});
if (context.isPending) {
return <p>Loading...</p>;
}
if (context.error) {
return <p className="error" >{context.error.toString()}</p>;
}
if (!context.referenceRecord) {
return <p>No details found</p>;
}
return (
<div>
<p>{context.referenceRecord.genre}</p>
<p>{context.referenceRecord.ISBN}</p>
</div>
);
}

Tip: As with <ReferenceFieldBase>, you can call <ReferenceOneFieldBase> as many times as you need in the same component, ra-core will only make one call to dataProvider.getManyReference() per reference.

PropRequiredTypeDefaultDescription
referenceRequiredstring-The name of the resource for the referenced records, e.g. ‘book_details’
targetRequiredstring-Target field carrying the relationship on the referenced resource, e.g. ‘book_id’
childrenOptional*Element-React component to render the referenced record.
renderOptional*(ReferenceFieldContext) => Element-A function that takes the ReferenceFieldContext and return a React element
emptyOptionalReactNode-The text or element to display when the referenced record is empty
filterOptionalObject{}Used to filter referenced records
linkOptional`stringFunction`edit
offlineOptionalReactNode-The text or element to display when there is no network connectivity
queryOptionsOptionalUseQueryOptions{}react-query client options
sortOptional{ field: String, order: 'ASC' or 'DESC' }{ field: 'id', order: 'ASC' }Used to order referenced records

* Either one of children or render is required.

You can pass any component of your own as children, to render the referenced record as you wish. You can access the list context using the useReferenceFieldContext hook.

const BookShow = () => (
<ReferenceOneFieldBase reference="book_details" target="book_id">
<BookDetails />
</ReferenceOneFieldBase>
);
const BookDetails = () => {
const { isPending, error, referenceRecord } = useReferenceFieldContext({
reference,
target,
});
if (isPending) {
return <p>Loading...</p>;
}
if (error) {
return <p className="error" >{error.toString()}</p>;
}
if (!referenceRecord) {
return <p>No details found</p>;
}
return (
<div>
<p>{referenceRecord.genre}</p>
<p>{referenceRecord.ISBN}</p>
</div>
);
}

Use empty to customize the text displayed when the related record is empty.

<ReferenceOneFieldBase label="Details" reference="book_details" target="book_id" empty="no detail">
...
</ReferenceOneFieldBase>

empty also accepts a translation key.

<ReferenceOneFieldBase label="Details" reference="book_details" target="book_id" empty="resources.books.not_found">
...
</ReferenceOneFieldBase>

empty also accepts a ReactNode.

<ReferenceOneFieldBase
label="Details"
reference="book_details"
target="book_id"
empty={<a href="/book_details/create">Create</a>}
>
...
</ReferenceOneFieldBase>

You can also use <ReferenceOneFieldBase> in a one-to-many relationship. In that case, the first record will be displayed. The filter prop becomes super useful in that case, as it allows you to select the appropriate record to display.

For instance, if a product has prices in many currencies, and you only want to render the price in euros, you can use:

<ReferenceOneFieldBase
reference="product_prices"
target="product_id"
filter={{ currency: "EUR" }}
>
...
</ReferenceOneFieldBase>

By default, <ReferenceOneFieldBase> populates the context with a link value that links to the edition page of the related record. You can disable this behavior by setting the link prop to false.

<ReferenceOneFieldBase label="Genre" reference="book_details" target="book_id" link={false}>
...
</ReferenceOneFieldBase>

You can also set the link prop to a string, which will be used as the link type. It can be either edit, show, a route path, or a function returning a route path based on the given record.

<ReferenceOneFieldBase
reference="book_details"
target="book_id"
link={record => `/custom/${record.id}`}
>
...
</ReferenceOneFieldBase>

When the user is offline, <ReferenceOneFieldBase> is smart enough to display the referenced record if it was previously fetched. However, if the referenced record has never been fetched before, <ReferenceOneFieldBase> displays an error message explaining that the app has lost network connectivity.

You can customize this error message by passing a React element or a string to the offline prop:

<ReferenceOneFieldBase
reference="book_details"
target="book_id"
offline={<p>No network, could not fetch data</p>}
>
...
</ReferenceOneFieldBase>
<ReferenceOneFieldBase
reference="book_details"
target="book_id"
offline="No network, could not fetch data">
...
</ReferenceOneFieldBase>

<ReferenceOneFieldBase> uses react-query to fetch the related record. You can set any of useQuery options via the queryOptions prop.

For instance, if you want to disable the refetch on window focus for this query, you can use:

<ReferenceOneFieldBase
label="Genre"
reference="book_details"
target="book_id"
queryOptions={{ refetchOnWindowFocus: false }}
>
...
</ReferenceOneFieldBase>

Alternatively to children you can pass a render function prop to <ReferenceOneFieldBase>. The render function prop will receive the ReferenceFieldContext as its argument, allowing to inline the render logic. When receiving a render function prop the <ReferenceOneFieldBase> component will ignore the children property.

const BookShow = () => (
<ReferenceOneFieldBase
reference="book_details"
target="book_id"
render={({ isPending, error, referenceRecord }) => {
if (isPending) {
return <p>Loading...</p>;
}
if (error) {
return <p className="error" >{error.toString()}</p>;
}
if (!referenceRecord) {
return <p>No details found</p>;
}
return (
<div>
<p>{referenceRecord.genre}</p>
<p>{referenceRecord.ISBN}</p>
</div>
);
}}
/>
);

The name of the resource to fetch for the related records.

For instance, if you want to display the details of a given book, the reference name should be book_details:

<ReferenceOneFieldBase label="Genre" reference="book_details" target="book_id">
...
</ReferenceOneFieldBase>

You can also use <ReferenceOneFieldBase> in a one-to-many relationship. In that case, the first record will be displayed. This is where the sort prop comes in handy. It allows you to select the appropriate record to display.

ReferenceOneFieldBase for one-to-many relationships

For instance, if you want to display the latest message in a discussion, you can use:

<ReferenceOneFieldBase
reference="messages"
target="discussion_id"
sort={{ field: "createdAt", order: "DESC" }}
>
...
</ReferenceOneFieldBase>

The name of the field carrying the relationship on the referenced resource.

For example, in the following schema, the relationship is carried by the book_id field:

┌──────────────┐ ┌──────────────┐
│ books │ │ book_details │
│--------------│ │--------------│
│ id │───┐ │ id │
│ title │ └──╼│ book_id │
│ published_at │ │ genre │
└──────────────┘ │ ISBN │
└──────────────┘

In that case, the target prop should be set to book_id:

<ReferenceOneFieldBase label="Genre" reference="book_details" target="book_id">
...
</ReferenceOneFieldBase>