<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.
Prop | Required | Type | Default | Description |
---|---|---|---|---|
reference | Required | string | - | The name of the resource for the referenced records, e.g. ‘book_details’ |
target | Required | string | - | Target field carrying the relationship on the referenced resource, e.g. ‘book_id’ |
children | Optional* | Element | - | React component to render the referenced record. |
render | Optional* | (ReferenceFieldContext) => Element | - | A function that takes the ReferenceFieldContext and return a React element |
empty | Optional | ReactNode | - | The text or element to display when the referenced record is empty |
filter | Optional | Object | {} | Used to filter referenced records |
link | Optional | `string | Function` | edit |
offline | Optional | ReactNode | - | The text or element to display when there is no network connectivity |
queryOptions | Optional | UseQueryOptions | {} | react-query client options |
sort | Optional | { field: String, order: 'ASC' or 'DESC' } | { field: 'id', order: 'ASC' } | Used to order referenced records |
* Either one of children or render is required.
children
Section titled “children”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>
filter
Section titled “filter”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>
offline
Section titled “offline”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>
queryOptions
Section titled “queryOptions”<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>
render
Section titled “render”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> ); }} />);
reference
Section titled “reference”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.
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>
target
Section titled “target”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>