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

如何在Sanity Studio输入组件中获取引用字段的完整数据?

解决Sanity Studio中withDocument无法获取完整Reference字段内容的问题

我之前也碰到过一模一样的问题!用withDocument高阶组件拿到的文档数据里,Reference类型字段确实只会返回_ref和_type这两个标识符——这是因为Sanity默认不会自动展开引用关联的完整文档内容。下面给你几个实用的解决方案:

方法一:用Sanity Client手动拉取引用文档

这是最直接的方式,利用Sanity内置的client来查询引用ID对应的完整文档:

import { useEffect, useState } from 'react'
import { withDocument } from 'sanity'
import client from 'part:@sanity/base/client'

const MyCustomInput = ({ document }) => {
  const [referencedDoc, setReferencedDoc] = useState(null)
  // 提取引用字段的ID
  const referenceId = document?.myReferenceField?._ref

  useEffect(() => {
    if (!referenceId) return

    // 通过GROQ查询获取完整引用文档
    client.fetch('*[_id == $id][0]', { id: referenceId })
      .then(data => setReferencedDoc(data))
      .catch(err => console.error('拉取引用文档失败:', err))
  }, [referenceId])

  return (
    <div>
      {referencedDoc ? (
        <p>引用文档标题:{referencedDoc.title}</p>
      ) : (
        <p>加载引用中...</p>
      )}
    </div>
  )
}

export default withDocument(MyCustomInput)

方法二:改用useDocumentNode钩子(更推荐的现代写法)

现在Sanity更推荐使用hooks替代HOC,useDocumentNode钩子可以直接获取当前文档,用法和上面类似:

import { useDocumentNode } from 'sanity'
import { useEffect, useState } from 'react'
import client from 'part:@sanity/base/client'

const MyCustomInput = () => {
  const { document } = useDocumentNode()
  const [referencedDoc, setReferencedDoc] = useState(null)
  const referenceId = document?.myReferenceField?._ref

  useEffect(() => {
    if (!referenceId) return

    client.fetch('*[_id == $id][0]', { id: referenceId })
      .then(data => setReferencedDoc(data))
      .catch(err => console.error('拉取引用文档失败:', err))
  }, [referenceId])

  // 你的组件渲染逻辑...
}

export default MyCustomInput

方法三:批量展开多个引用(适合复杂场景)

如果你的文档里有多个引用字段或者引用数组,可以用GROQ的->语法一次性展开所有需要的内容,减少请求次数:

useEffect(() => {
  if (!document?._id) return

  client.fetch(`
    *[_id == $documentId][0]{
      ..., // 保留原文档所有字段
      singleReference->, // 展开单个引用字段
      referenceArray[]-> // 展开引用数组里的每一项
    }
  `, { documentId: document._id })
    .then(fullDocument => {
      // fullDocument里就包含了所有展开后的引用内容
      console.log('带完整引用的文档:', fullDocument)
    })
    .catch(err => console.error('拉取完整文档失败:', err))
}, [document?._id])

注意事项

  • 确保你的client拥有读取引用文档的权限,避免权限不足导致拉取失败
  • 记得处理加载状态和空值情况,防止出现Cannot read property 'xxx' of null这类报错
  • 如果是引用数组,要注意遍历处理每一项的展开

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:45:26