Skip to main content
Version: 4.xx.xx

3. Adding Show Page

Show page is the page where you can see the record. In this tutorial, we will create the show page for the blog_posts resource.

Creating Show Page

First, let's create our file under the src/pages/blog-posts folder. We will name it show.tsx. Then, we will copy the show page code generated by Inferencer and paste it into the file.

To copy the code and paste it into the file, follow the steps below:

  1. Navigate to the localhost:3000/blog-posts in your browser.

  2. To open the show page, click any "Show" button in the "Actions" column of the table.

  3. On the show page, click on the "Show Code" button in the bottom right corner of the page.

  4. You can see the show page code generated by Inferencer. Click on the "Copy" button to copy the code.

  5. Paste the code into the you created, show.tsx file.

You can see the show page code generated by Inferencer below:

http://localhost:3000
setInitialRoutes(['/blog-posts/show/123'])

import {
ErrorComponent,
ThemedLayout,
notificationProvider,
} from '@refinedev/antd'
import { Refine } from '@refinedev/core'
import { AntdInferencer } from '@refinedev/inferencer/antd'
import routerBindings, {
NavigateToResource,
UnsavedChangesNotifier,
} from '@refinedev/react-router-v6'
import dataProvider from '@refinedev/simple-rest'

import { BrowserRouter, Outlet, Route, Routes } from 'react-router-dom'

import '@refinedev/antd/dist/reset.css'

const App: React.FC = () => {
return (
<BrowserRouter>
<Refine
routerProvider={routerBindings}
dataProvider={dataProvider('https://api.fake-rest.refine.dev')}
notificationProvider={notificationProvider}
resources={[
{
name: 'blog_posts',
list: '/blog-posts',
show: '/blog-posts/show/:id',
create: '/blog-posts/create',
edit: '/blog-posts/edit/:id',
},
]}
options={{
syncWithLocation: true,
warnWhenUnsavedChanges: true,
}}
>
<Routes>
<Route
element={
<ThemedLayout>
<Outlet />
</ThemedLayout>
}
>
<Route
index
element={<NavigateToResource resource="blog_posts" />}
/>

<Route path="blog-posts">
<Route index element={<AntdInferencer />} />
<Route path="show/:id" element={<AntdInferencer />} />
<Route path="edit/:id" element={<AntdInferencer />} />
<Route path="create" element={<AntdInferencer />} />
</Route>

<Route path="*" element={<ErrorComponent />} />
</Route>
</Routes>
<UnsavedChangesNotifier />
</Refine>
</BrowserRouter>
)
}

render(<App />)

Instead of coding the show page component from scratch, Inferencer created the required code base on API response, so that we can customize.

Understanding the Show Component

We will go through the show page components and hooks one by one.

Handling Relationships

In the show page, we have a single record. The record may have relationships with other resources.

For example, the blog_posts resource has a relationship with the categories resource. In this case, we can use the useOne hook provided by refine. This hook allows us to fetch single record data by using the id and resource parameters.

Refer to the useOne documentation for more information &#8594

In the auto-generated show page code, Inferencer used the useOne hook to fetch the category data of the blog post record.

const { data: categoryData, isLoading: categoryIsLoading } = useOne({
resource: 'categories',
id: record?.category?.id || '',
})

To ensure that the related data is only fetched after the blog post record has been successfully retrieved, we can use the queryOptions object. By setting the enabled property to true only if the record variable is truthy, we can control when the related data is fetched like below:

const { data: categoryData, isLoading: categoryIsLoading } = useOne({
resource: 'categories',
id: record?.category?.id || '',
queryOptions: {
enabled: !!record,
},
})

Adding the Show Page to the App

Now that we have created the show page, we need to add it to the App.tsx file.

  1. Open src/App.tsx file on your editor.

  2. Import the created BlogPostShow component.

  3. Replace the AntdInferencer component with the BlogPostShow component.

src/App.tsx
import {
ErrorComponent,
ThemedLayout,
notificationProvider,
} from '@refinedev/antd'
import { Refine } from '@refinedev/core'
import { AntdInferencer } from '@refinedev/inferencer/antd'
import routerBindings, {
NavigateToResource,
UnsavedChangesNotifier,
} from '@refinedev/react-router-v6'
import dataProvider from '@refinedev/simple-rest'

import { BrowserRouter, Outlet, Route, Routes } from 'react-router-dom'

import { BlogPostEdit } from 'pages/blog-posts/edit'
import { BlogPostList } from 'pages/blog-posts/list'
import { BlogPostShow } from 'pages/blog-posts/show'

import '@refinedev/antd/dist/reset.css'

const App: React.FC = () => {
return (
<BrowserRouter>
<Refine
routerProvider={routerBindings}
dataProvider={dataProvider('https://api.fake-rest.refine.dev')}
notificationProvider={notificationProvider}
resources={[
{
name: 'blog_posts',
list: '/blog-posts',
show: '/blog-posts/show/:id',
create: '/blog-posts/create',
edit: '/blog-posts/edit/:id',
},
]}
options={{
syncWithLocation: true,
warnWhenUnsavedChanges: true,
}}
>
<Routes>
<Route
element={
<ThemedLayout>
<Outlet />
</ThemedLayout>
}
>
<Route
index
element={<NavigateToResource resource="blog_posts" />}
/>

<Route path="blog-posts">
<Route index element={<BlogPostList />} />
<Route path="show/:id" element={<BlogPostShow />} />
<Route path="edit/:id" element={<BlogPostEdit />} />
<Route path="create" element={<AntdInferencer />} />
</Route>

<Route path="*" element={<ErrorComponent />} />
</Route>
</Routes>
<UnsavedChangesNotifier />
</Refine>
</BrowserRouter>
)
}

export default App

Now, we can see the show page in the browser at localhost:3000/blog-posts/show/123



Checklist