📅  最后修改于: 2023-12-03 15:07:58.049000             🧑  作者: Mango
最近在使用 Gatsby 开发网站时,发现了一个常见的错误: React Hook “useStaticQuery” may be executed more than once. Possibly because it is called in a loop.”
这个错误通常发生在你在多次调用 useStaticQuery
的情况下,特别是在一个循环内部调用。在此文章中,我们将探讨如何在函数中正确地使用 useStaticQuery
。
useStaticQuery
是 Gatsby 的一个内置 React Hook,用于查询静态数据。使用这个 Hook,你可以在页面组件中轻松地查询 GraphQL 数据。与普通的 GraphQL 查询不同,useStaticQuery
查询是在构建时处理的。
在函数中调用 useStaticQuery
时,你需要确保它只被调用一次。否则,你将会收到在开发时产生的上述错误。下面是一个不当使用 useStaticQuery
的例子:
import React from "react"
import { useStaticQuery, graphql } from "gatsby"
const MyComponent = () => {
const data = ["foo", "bar"].map(name =>
useStaticQuery(graphql`
query {
allMarkdownRemark(filter: { frontmatter: { name: { eq: $${name} } } }) {
nodes {
frontmatter {
title
}
}
}
}
`)
)
return (
<div>
{data.map(node => (
<div key={node.frontmatter.title}>{node.frontmatter.title}</div>
))}
</div>
)
}
export default MyComponent
在上面的例子中,我们在循环中调用了 useStaticQuery
,这将导致多次查询相同的数据,从而触发错误。正确的做法是将 useStaticQuery
放在组件的外部,如下所示:
import React from "react"
import { useStaticQuery, graphql } from "gatsby"
const query = graphql`
query MyQuery($name: String!) {
allMarkdownRemark(filter: { frontmatter: { name: { eq: $name } } }) {
nodes {
frontmatter {
title
}
}
}
}
`
const MyComponent = () => {
const data = ["foo", "bar"].map(name => {
const result = useStaticQuery(query, { variables: { name: name } })
return result.allMarkdownRemark.nodes[0]
})
return (
<div>
{data.map(node => (
<div key={node.frontmatter.title}>{node.frontmatter.title}</div>
))}
</div>
)
}
export default MyComponent
在这个更改后,我们将查询定义为一个常量,并在循环中使用它。这将使 useStaticQuery
只在组件的挂载过程中调用一次。此外,我们还将 GraphQL 查询中的变量提取到了 variables
选项中。
在使用 useStaticQuery
时,请确保它只被调用一次。如果你需要在循环中调用它,请将查询定义为常量并在循环外部使用。