react-admin+Next.js创建记录时record.section未定义错误
问题:React Admin 创建记录后 record.section 未定义报错
在 Next.js 14.2.14 + React Admin 5.3.0 项目中,创建units记录时触发错误:TypeError: 无法访问属性"name",record.section未定义,但刷新页面后错误消失。仅当recordRepresentation使用嵌套对象record.section.name时出现此问题,设为"name"则正常。
相关代码片段
App.tsx(React Admin 资源配置)
// src/app/admin/App.tsx const dataProvider = simpleRestProvider("/api"); const App = () => { return ( <Admin dataProvider={dataProvider}> {/* ... */} <Resource name="units" list={UnitList} create={UnitCreate} edit={UnitEdit} recordRepresentation={(record) => `${record.section.name} - ${record.name}`} /> {/* ... */} </Admin> ); };
接口 POST 实现(route.ts)
// src/app/api/(admin)/units/route.ts import { auth } from "@/auth"; import { db } from "@/db"; import { units } from "@/db/schema"; import { NextResponse } from "next/server"; export const POST = async (req: Request) => { const session = await auth(); if (!session) { return new NextResponse("Unauthorized", { status: 401 }); } if (!session.user || session.user.role !== "admin") { return new NextResponse("Forbidden", { status: 403 }); } const body = await req.json(); const data = await db .insert(units) .values({ ...body, }) .returning(); return NextResponse.json(data[0]); };
问题原因
创建记录后,React Admin 会立即使用接口返回的新记录渲染recordRepresentation,但当前POST接口返回的data[0]是 Drizzle 插入后直接返回的基础记录——仅包含sectionId,没有嵌套的section对象(关联查询只在GET接口中通过with: { section: true }实现)。刷新页面后调用的GET接口返回了带完整关联数据的记录,因此错误消失。
添加隐藏的section.name字段无效,因为该字段仅在列表页生效,不影响创建接口返回的记录结构。
解决方案
方案1:修改POST接口,返回带关联section的完整记录
插入记录后,通过新记录的id查询包含关联section的完整数据再返回:
export const POST = async (req: Request) => { // 省略权限校验代码 const body = await req.json(); // 插入基础记录 const inserted = await db .insert(units) .values({ ...body }) .returning(); // 查询包含section关联的完整记录 const fullRecord = await db.query.units.findFirst({ where: (unitsTable, { eq }) => eq(unitsTable.id, inserted[0].id), with: { section: true }, }); return NextResponse.json(fullRecord); };
方案2:在recordRepresentation中添加空值保护
避免因section不存在导致报错,同时保证显示友好:
recordRepresentation={(record) => { const sectionName = record.section?.name || `未关联章节(ID: ${record.sectionId})`; return `${sectionName} - ${record.name}`; }}
方案3:自定义DataProvider,覆盖create方法
基于simpleRestProvider扩展create方法,创建后自动调用getOne获取完整记录:
import { simpleRestProvider, DataProvider } from 'react-admin'; const dataProvider: DataProvider = { ...simpleRestProvider("/api"), create: async (resource, params) => { // 执行原创建请求 const createResponse = await simpleRestProvider("/api").create(resource, params); // 获取完整记录 const fullRecord = await simpleRestProvider("/api").getOne(resource, { id: createResponse.data.id }); return { ...createResponse, data: fullRecord.data }; }, };
内容的提问来源于stack exchange,提问作者thrumbo
相关产品推荐
相关产品推荐

