React-Admin侧边栏ReferenceManyField加载异常求助
解决React-Admin中Show组件侧边栏关联数据异常问题
问题原因
你遇到的"Error: target and id are required"以及侧边栏偶尔显示"无结果"的问题,核心原因是:<Show>组件的aside属性渲染的组件,不在<SimpleShowLayout>提供的RecordContext上下文范围内。
<SimpleShowLayout>内部会自动注入当前记录的上下文,所以放在其中的<ReferenceManyField>能正常获取到当前记录的ID来构建关联查询;而侧边栏的组件默认无法访问这个上下文,导致<ReferenceManyField>缺少必要的查询参数,从而报错。刷新后正常是因为页面重新加载时上下文已完成初始化,组件能拿到记录数据。
解决方案
下面提供两种可靠的修复方式:
方案1:手动传递当前记录给侧边栏组件
在父组件中获取当前记录,直接传递给侧边栏的RelatedR3s组件:
修改R3Show组件
import { Show, SimpleShowLayout, useRecordContext } from 'react-admin'; import { PageTitle } from './your-components'; // 替换为实际路径 import { RelatedR3s } from './RelatedR3s'; function R3Show() { // 获取当前记录上下文 const record = useRecordContext(); return ( <Show title={<PageTitle />} aside={<RelatedR3s record={record} />}> <SimpleShowLayout sx={{ border: '2px solid HotPink', }} > <RepairStatus label={`resources.r3s.customFields.statusR3s`} /> <RepairDuration /> <TextField source='remark' /> {/* 其他字段 */} </SimpleShowLayout> </Show> ); }
修改RelatedR3s组件
接收传递的record属性,手动设置关联查询的过滤条件,并添加加载状态判断:
import { useTranslate, ReferenceManyField, Datagrid, RepairStatus, RepairDuration, TextField, DateField, ReferenceField, ChipField, Pagination, CircularProgress } from 'react-admin'; import { Box, Divider, Chip } from '@mui/material'; export function RelatedR3s({ record, pagination = <Pagination /> }) { const translate = useTranslate(); // 记录未加载完成时显示加载动画 if (!record) { return <CircularProgress sx={{ margin: '1rem' }} />; } return ( <Box sx={{ marginLeft: '1rem', }} > <Divider sx={{ marginBottom: '1rem', }} > <Chip label={translate('resources.r3s.customFields.relatedR3s')} /> </Divider> <ReferenceManyField reference='r3s' target='machine_id' // 手动指定过滤条件,替代原来的source属性 filter={{ machine_id: record.id }} sort={{ field: 'r3Date', order: 'DESC' }} perPage={7} allowEmpty={true} pagination={pagination} > <Datagrid bulkActionButtons={false} rowClick='show' > <RepairStatus label={translate('resources.r3s.customFields.statusR3s')} /> <RepairDuration label={translate('resources.r3s.customFields.repairDuration')} /> <TextField source='r3Number' /> <DateField source='r3Date' locales='zh-CN' /> <ReferenceField source='applicant_id' reference='profiles' link='show' > <ChipField source='name' /> </ReferenceField> </Datagrid> </ReferenceManyField> </Box> ); }
方案2:在侧边栏组件中直接获取记录上下文
利用useRecordContext钩子在RelatedR3s内部获取当前记录,无需修改父组件:
import { useTranslate, ReferenceManyField, Datagrid, RepairStatus, RepairDuration, TextField, DateField, ReferenceField, ChipField, Pagination, CircularProgress, useRecordContext } from 'react-admin'; import { Box, Divider, Chip } from '@mui/material'; export function RelatedR3s({ pagination = <Pagination /> }) { const translate = useTranslate(); const record = useRecordContext(); if (!record) { return <CircularProgress sx={{ margin: '1rem' }} />; } return ( <Box sx={{ marginLeft: '1rem' }}> <Divider sx={{ marginBottom: '1rem' }}> <Chip label={translate('resources.r3s.customFields.relatedR3s')} /> </Divider> <ReferenceManyField reference='r3s' target='machine_id' filter={{ machine_id: record.id }} sort={{ field: 'r3Date', order: 'DESC' }} perPage={7} allowEmpty={true} pagination={pagination} > {/* Datagrid内容同方案1 */} </ReferenceManyField> </Box> ); }
关键说明
- 两种方案的核心都是确保
RelatedR3s组件能获取到当前记录,并为ReferenceManyField提供明确的查询条件(通过filter属性),避免依赖上下文自动注入的source。 - 添加
!record的判断是为了处理记录未加载完成的情况,避免组件渲染时抛出空值错误。
内容的提问来源于stack exchange,提问作者Zovitch
相关产品推荐
相关产品推荐

