useShowController
useShowController
is the hook that handles all the controller logic for Show views. It’s used by <Show>
and <ShowBase>
.
This hook takes care of three things:
- it reads the resource name and id from the resource context and browser location
- it fetches the record from the data provider via
dataProvider.getOne()
, - it computes the default page title
Usage
You can use useShowController
to create your own custom Show view, like this one:
import { useShowController, RecordContextProvider, SimpleShowLayout } from 'react-admin';
const PostShow = () => {
const {
defaultTitle, // the translated title based on the resource, e.g. 'Post #123'
error, // error returned by dataProvider when it failed to fetch the record. Useful if you want to adapt the view instead of just showing a notification using the `onError` side effect.
isFetching, // boolean that is true while the record is being fetched, and false once the record is fetched
isLoading, // boolean that is true until the record is available for the first time
record, // record fetched via dataProvider.getOne() based on the id from the location
refetch, // callback to refetch the record via dataProvider.getOne()
resource, // the resource name, deduced from the location. e.g. 'posts'
} = useShowController();
if (isLoading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error!</div>;
}
return (
<RecordContextProvider value={record}>
<h1>{defaultTitle}</h1>
<SimpleShowLayout>
<TextField source="title" />
...
</SimpleShowLayout>
</RecordContextProvider>
);
};
This custom Show view has no action buttons - it’s up to you to add them in pure React.
Tip: Use <ShowBase>
instead of useShowController
if you need a component version of that hook.
Parameters
useShowController
expects one parameter argument. It’s an object with the following attributes:
Name | Required | Type | Default | Description |
---|---|---|---|---|
disable Authentication |
Optional | boolean |
Set to true to disable the authentication check. |
|
id |
Optional | string |
The record identifier. If not provided, it will be deduced from the URL. | |
queryOptions |
Optional | object |
The options to pass to the useQuery hook. |
|
resource |
Optional | string |
The resource name, e.g. posts |
disableAuthentication
By default, the useShowController
hook will automatically redirect the user to the login page if the user is not authenticated. If you want to disable this behavior and allow anonymous access to a show page, set the disableAuthentication
prop to true
.
import { useShowController } from 'react-admin';
const PostShow = () => {
const { record } = useShowController({ disableAuthentication: true });
return (
<div>
<h1>{record.title}</h1>
<p>{record.body}</p>
</div>
);
};
id
By default, useShowController
reads the record id from the browser location. But by passing an id
prop, you can run the controller logic on an arbitrary record id:
const Post1234Show = () => {
const { record } = useShowController({ id: 1234 });
return (
<div>
<h1>{record.title}</h1>
<p>{record.body}</p>
</div>
);
};
queryOptions
useShowController
accepts a queryOptions
prop to pass options to the react-query client.
This can be useful e.g. to override the default error side effect. By default, when the dataProvider.getOne()
call fails at the dataProvider level, react-admin shows an error notification and refreshes the page.
You can override this behavior and pass custom side effects by providing a custom queryOptions
prop:
import * as React from 'react';
import { useNotify, useRefresh, useRedirect, ShowBase, SimpleShowLayout } from 'react-admin';
const PostShow = props => {
const notify = useNotify();
const refresh = useRefresh();
const redirect = useRedirect();
const onError = (error) => {
notify(`Could not load post: ${error.message}`, { type: 'error' });
redirect('/posts');
refresh();
};
const {
defaultTitle,
error,
isLoading,
record,
} = useShowController({ queryOptions: { onError } });
if (isLoading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error!</div>;
}
return (
<RecordContextProvider value={record}>
<h1>{defaultTitle}</h1>
<SimpleShowLayout>
<TextField source="title" />
...
</SimpleShowLayout>
</RecordContextProvider>
);
}
The onError
function receives the error from the dataProvider call (dataProvider.getOne()
), which is a JavaScript Error object (see the dataProvider documentation for details).
The default onError
function is:
(error) => {
notify('ra.notification.item_doesnt_exist', { type: 'error' });
redirect('list', resource);
refresh();
}
resource
By default, useShowController
reads the resource name from the resource context. But by passing a resource
prop, you can run the controller logic on an arbitrary resource:
const PostShow = () => {
const { record } = useShowController({ resource: 'posts'; id: 1234 });
return (
<div>
<h1>{record.title}</h1>
<p>{record.body}</p>
</div>
);
};
Controlled Mode
By default, useShowController
reads the resource name from the resource context, and the record id from the browser location.
But by passing resource
and id
props, you can run the controller logic outside these contexts:
import { useShowController } from 'react-admin';
import ShowView from './ShowView';
const MyShow = () => {
const controllerProps = useShowController({ resource: 'posts', id: 1234 });
return <ShowView {...controllerProps} />;
};