You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Admin:Show页面中useRecordContext()返回undefined问题

问题原因

你遇到的核心问题是钩子调用的时机和上下文范围不对。useRecordContext、useShowContext这些钩子需要在由<Show>或useShowController创建的上下文内部才能获取到数据,但你现在是在CardShow组件的顶层直接调用它们——此时<Show>组件还没完成渲染,上下文还没被注入,自然拿不到值。而<TextField>能正常显示,是因为它被包裹在<Show>/<SimpleShowLayout>内部,处于正确的上下文里。

解决方法

下面给两种可行的修复方案:

方案一:把钩子逻辑移到子组件中

把需要使用useRecordContext等钩子的代码放到一个子组件里,让子组件处于<Show>的上下文范围内:

// ./cards/CardShow.tsx
import { useParams } from 'react-router-dom';
import { useRecordContext, useShowContext } from 'react-admin';
import { Show, SimpleShowLayout, TextField } from 'react-admin';

// 子组件:处于Show的上下文内
const CardShowContent = () => {
    const record = useRecordContext();
    console.log(record); // 现在能拿到正确数据了
    
    const { isLoading, record: record2 } = useShowContext();
    console.log(record2); // 正常返回数据

    return (
        <SimpleShowLayout>
            <TextField source="id" />
            <TextField source="title" />
        </SimpleShowLayout>
    )
};

const CardShow = () => {
    const { id } = useParams();
    console.log(id); // 正常显示id

    return (
        <Show>
            <CardShowContent />
        </Show>
    )
};
export default CardShow;

方案二:手动使用useShowController并提供上下文

如果想在顶层组件里直接获取数据,可以自己调用useShowController,然后用RecordContext.Provider把数据传递给子组件,注意此时要把<Show>换成<ShowView>(避免重复创建控制器):

// ./cards/CardShow.tsx
import { useParams } from 'react-router-dom';
import { useRecordContext, useShowController, RecordContext, ShowView, SimpleShowLayout, TextField } from 'react-admin';

const CardShow = () => {
    const { id } = useParams();
    console.log(id); // 正常显示id
    
    // 手动调用控制器,获取数据
    const { data, isLoading } = useShowController({ recordId: id });
    console.log(data); // 现在能拿到数据了

    if (isLoading) return <div>Loading...</div>;

    return (
        <RecordContext.Provider value={data}>
            <ShowView>
                <SimpleShowLayout>
                    <TextField source="id" />
                    <TextField source="title" />
                </SimpleShowLayout>
            </ShowView>
        </RecordContext.Provider>
    )
};
export default CardShow;
关键说明
  • <Show>组件内部已经封装了useShowController和上下文注入逻辑,所以它的子组件才能访问到记录数据。
  • 所有依赖React Admin上下文的钩子,都必须在对应的Provider(由<Show>、<List>、<Edit>等组件或useXXXController钩子创建)的范围内调用。

内容的提问来源于stack exchange,提问作者benoit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 07:13:01