如何在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
相关产品推荐
相关产品推荐

