📌  相关文章
📜  在函数中调用错误 React Hook “useStaticQuery” - Javascript (1)

📅  最后修改于: 2023-12-03 15:07:58.049000             🧑  作者: Mango

在函数中调用错误 React Hook “useStaticQuery”

最近在使用 Gatsby 开发网站时,发现了一个常见的错误: React Hook “useStaticQuery” may be executed more than once. Possibly because it is called in a loop.”

这个错误通常发生在你在多次调用 useStaticQuery 的情况下,特别是在一个循环内部调用。在此文章中,我们将探讨如何在函数中正确地使用 useStaticQuery

什么是 useStaticQuery

useStaticQuery 是 Gatsby 的一个内置 React Hook,用于查询静态数据。使用这个 Hook,你可以在页面组件中轻松地查询 GraphQL 数据。与普通的 GraphQL 查询不同,useStaticQuery 查询是在构建时处理的。

在函数中使用 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 时,请确保它只被调用一次。如果你需要在循环中调用它,请将查询定义为常量并在循环外部使用。