为啥 Gatsby 的两个不同布局上的两个 StaticQuery 元素不能具有相同的名称?
Posted
技术标签:
【中文标题】为啥 Gatsby 的两个不同布局上的两个 StaticQuery 元素不能具有相同的名称?【英文标题】:Why is it not possible to have the same name of two StaticQuery elements on two different layouts for Gatsby?为什么 Gatsby 的两个不同布局上的两个 StaticQuery 元素不能具有相同的名称? 【发布时间】:2019-08-18 07:00:39 【问题描述】:例如,如果我有两个布局并且我想使用相同的布局,我需要为每个布局命名不同的 StaticQuery:
layoutA.js
const LayoutA = ( children ) => (
<StaticQuery
query=graphql`
query SiteTitleQuery
site
siteMetadata
title
`
layoutB.js
const LayoutB = ( children ) => (
<StaticQuery
query=graphql`
query SiteTitleQuery
site
siteMetadata
title
`
以上会导致如下错误:
错误 GraphQL 错误 编译您网站的 GraphQL 查询。错误:RelayParser:遇到重复 一个或多个文档的定义:每个文档必须有一个 唯一的名称。重复文件: - 站点标题查询
在某种程度上,它们是两个不同的静态查询,它们用于两个不同的页面(布局)并且应该是可以接受的,除非静态查询可以在页面之间共享。
【问题讨论】:
【参考方案1】:我个人并不真正关心这个名字,事实上你可以完全忽略这个名字,盖茨比会自己使用一些独特的、随机的名字。如果你选择给它一个名字,你必须给它两个不同的名字,没有解决方法。
但是,您可以使用 Hook 版本的 StaticQuery:useStaticQuery
这样你就没有重复了。
所以在一个新组件中你可以写如下:
import useStaticQuery, graphql from 'gatsby'
function useTitle()
const data = useStaticQuery(graphql`
query
site
siteMetadata
title
`)
return data.site.siteMetadata.title
export default useTitle
并在你的布局中使用它:
import useTitle from './useTitle'
const LayoutA = ( children ) =>
const title = useTitle()
return <div><h1>title</h1>children</div>
【讨论】:
【参考方案2】:@LekoArts 提供了很好的解决方案。我想回答这个问题:为什么不能在 2 个不同的文件中拥有相同的查询名称?
Gatsby extracts all graphql queries from your files & 独立执行它们。如果用户省略了查询名称,将为该查询生成一个名称;但如果它确实有名称,它将与所有其他查询在同一个空间中。
这个系统的一个好处是您可以在任何文件中导出片段,并且可以在其他查询中使用它。插件和包也利用了这一点,例如gatsby-image
和GatsbyImageSharpFluid
和GatsbyImageSharpFixed
。
除了使用 useStaticQuery
钩子(仅适用于 React ^16.8)之外,重复的查询也可以使用 StaticQuery
提取到更小的组件中或转换为 fragment。
【讨论】:
以上是关于为啥 Gatsby 的两个不同布局上的两个 StaticQuery 元素不能具有相同的名称?的主要内容,如果未能解决你的问题,请参考以下文章