在 Gatsby、GraphQL 和 Sanity 中使用 _raw 和正常数据进行推理
Reasoning with _raw and normal data in Gatsby, GraphQL and Sanity
我刚刚开始使用 Gatsby with the Sanity 无头 CMS。
在大多数情况下,它非常简单;但是了解通过 GraphQL 查询数据的最佳实践仍然困扰着我。我目前的做法是在 GraphQL 操场上疯狂地点击我的 CMS 结构并找到我想要的东西。这行得通,但这种方法缺乏统一性让我感到不安。
例如,如果我想要 CMS 中某处的英雄图片,我需要执行如下操作:
query SomePageQuery($id: String) {
sanitySomePage(id: { eq: $id }) {
id
heroImage {
asset {
fluid(maxWidth: 1500) {
...GatsbySanityImageFluid
}
}
}
}
}
但是如果我想要一些 PortableText 块,那么我需要查询任何类型的相应 _raw
字段。所以,如果我的类型是 introText
,Gatsby 也提供了 _rawIntroText
。我只能从这个 _raw
版本的数据中获得完整的 PortableText。像这样:
query SomePageQuery($id: String) {
sanitySomePage(id: { eq: $id }) {
id
_rawIntroText
}
}
似乎,对于某些数据您可以使用 [Type]
,有时您 必须 使用 _raw[Type]
.
关于为什么是这种情况的文档并不多。我不确定这是通过 Sanity 还是 Gatsby 强制执行的。
我想我的问题是,为什么 _raw[Anything]
存在于 Gatsby and/or Sanity 世界中,人们如何决定使用哪个(除了在 GraphQL 中反复试验之外游乐场和运行时)?
这来自 Sanity 构建和维护的 gatsby-source-sanity 插件。希望来自 Sanity 的人可以提供更多上下文,但实际上 _raw[FieldName]
条目 return 字段的原始 JSON 数据。无前缀字段(例如 fieldName
)可能不是您想要的——它只包含有关数据的一些元数据。
我倾向于提取 _raw[FieldName]
数据,然后将其直接传递到 @sanity/block-content-to-react
组件中,如下所示:
import React from "react"
import { graphql } from "gatsby"
import SanityBlockContent from "@sanity/block-content-to-react"
export default ({ data: { page } }) => (
<SanityBlockContent
blocks={page.textContent}
projectId={process.env.GATSBY_SANITY_PROJECT_ID}
dataset={process.env.GATSBY_SANITY_DATASET}
/>
)
export const query = graphql`
query SomePageQuery($id: String) {
page: sanitySomePage(id: { eq: $id }) {
textContent: _rawTextContent
}
}
`
请注意,我使用 GraphQL 别名继续在我的组件中将字段引用为 textContent
,而不是将组件耦合到此 GraphQL 模式的细节。
您不需要为 Sanity 图像使用 Gatsby 图像,因为它们有自己的图像转换管道。相反,您可以只获取 asset { _id }
,然后像这样使用 @sanity/client
来生成图像 url:
import sanityClient from "@sanity/client"
import sanityImageUrl from "@sanity/image-url"
const client = sanityClient({
dataset: process.env.GATSBY_SANITY_DATASET,
projectId: process.env.GATSBY_SANITY_PROJECT_ID,
useCdn: true,
})
const builder = sanityImageUrl(client)
builder.image({ _id: "..." }).width(400).dpr(2).url()
我刚刚开始使用 Gatsby with the Sanity 无头 CMS。
在大多数情况下,它非常简单;但是了解通过 GraphQL 查询数据的最佳实践仍然困扰着我。我目前的做法是在 GraphQL 操场上疯狂地点击我的 CMS 结构并找到我想要的东西。这行得通,但这种方法缺乏统一性让我感到不安。
例如,如果我想要 CMS 中某处的英雄图片,我需要执行如下操作:
query SomePageQuery($id: String) {
sanitySomePage(id: { eq: $id }) {
id
heroImage {
asset {
fluid(maxWidth: 1500) {
...GatsbySanityImageFluid
}
}
}
}
}
但是如果我想要一些 PortableText 块,那么我需要查询任何类型的相应 _raw
字段。所以,如果我的类型是 introText
,Gatsby 也提供了 _rawIntroText
。我只能从这个 _raw
版本的数据中获得完整的 PortableText。像这样:
query SomePageQuery($id: String) {
sanitySomePage(id: { eq: $id }) {
id
_rawIntroText
}
}
似乎,对于某些数据您可以使用 [Type]
,有时您 必须 使用 _raw[Type]
.
关于为什么是这种情况的文档并不多。我不确定这是通过 Sanity 还是 Gatsby 强制执行的。
我想我的问题是,为什么 _raw[Anything]
存在于 Gatsby and/or Sanity 世界中,人们如何决定使用哪个(除了在 GraphQL 中反复试验之外游乐场和运行时)?
这来自 Sanity 构建和维护的 gatsby-source-sanity 插件。希望来自 Sanity 的人可以提供更多上下文,但实际上 _raw[FieldName]
条目 return 字段的原始 JSON 数据。无前缀字段(例如 fieldName
)可能不是您想要的——它只包含有关数据的一些元数据。
我倾向于提取 _raw[FieldName]
数据,然后将其直接传递到 @sanity/block-content-to-react
组件中,如下所示:
import React from "react"
import { graphql } from "gatsby"
import SanityBlockContent from "@sanity/block-content-to-react"
export default ({ data: { page } }) => (
<SanityBlockContent
blocks={page.textContent}
projectId={process.env.GATSBY_SANITY_PROJECT_ID}
dataset={process.env.GATSBY_SANITY_DATASET}
/>
)
export const query = graphql`
query SomePageQuery($id: String) {
page: sanitySomePage(id: { eq: $id }) {
textContent: _rawTextContent
}
}
`
请注意,我使用 GraphQL 别名继续在我的组件中将字段引用为 textContent
,而不是将组件耦合到此 GraphQL 模式的细节。
您不需要为 Sanity 图像使用 Gatsby 图像,因为它们有自己的图像转换管道。相反,您可以只获取 asset { _id }
,然后像这样使用 @sanity/client
来生成图像 url:
import sanityClient from "@sanity/client"
import sanityImageUrl from "@sanity/image-url"
const client = sanityClient({
dataset: process.env.GATSBY_SANITY_DATASET,
projectId: process.env.GATSBY_SANITY_PROJECT_ID,
useCdn: true,
})
const builder = sanityImageUrl(client)
builder.image({ _id: "..." }).width(400).dpr(2).url()