以编程方式从 API 数据创建 Gatsby 页面

Programmatically create Gatsby pages from API data

这是一个与 类似的问题。

我正在寻求使用 createPage 或 createPages 以编程方式创建页面的帮助,但我遇到了问题 - 文档提供了从 markdown 文件创建页面的示例,但解释不多。

我正在使用 plugins\characters\gatsby-node.js 中的插件将 Rick & Morty API 中的数据添加到 GraphQL 数据层。如果相关,我的插件位于问题的底部。

插件确实成功添加了数据,因为我可以在 http://localhost:8000/___graphql 中看到数据,并且我已经成功地在(静态)页面中使用了数据。

我迷路的地方是我希望能够为每个单独的角色创建一个页面,为每个页面使用 url characters/<characterIdHere>。我知道我需要向我的(主版本或插件版本...?)gatsby-node.js 文件添加一些逻辑,但这是我坚持的部分。我不知道我需要在 gatsby-node.js 文件中放入什么。 我能找到的示例都使用 json 或 markdown 文件,我想使用我已经提取的数据(从 API)到 gatsby 的数据层。我显然已经研究了几个小时并在询问之前尝试了一下,但没有任何运气。

我要创建的页面上的组件应如下所示:

const CharactersViewSingle = ({ character}) => {
  return (
    <div>
      <Helmet>
        <title>{character.name && character.name}</title>
      </Helmet>
      <NavBar />
      <CharactersViewBox character={character} width={300} height={520} />
    </div>
  )
}

以上代码取自我使用create-react-app时组件返回的内容

我用来获取其他(静态)页面上的数据的 graphQL 查询(这显然反映了我想使用的数据的结构)如下所示:

export const query = graphql`
  query CharactersQuery {
    allCharacters(limit: 5) {
      edges {
        node {
          id
          name
          status
          gender
          image
        }
      }
    }
  }
`

插件代码:

const axios = require("axios")

exports.sourceNodes = async ({
  actions,
  createNodeId,
  createContentDigest,
}) => {
  const { createNode } = actions

  const integerList = (start, length) =>
    Array.from({ length: length }, (v, k) => k + start)

  const rickMortyURL = `https://rickandmortyapi.com/api/character/${integerList(
    1,
    493
  )}`

  const rickMorty = await axios.get(rickMortyURL)
  const query = await axios.get(rickMortyURL)
  rickMorty.data.forEach(character => {
    const nodeContent = JSON.stringify(character)
    const nodeMeta = {
      id: character.id.toString(),
      //id: createNodeId(`char-data-${character.id}`),
      parent: null,
      children: [],
      internal: {
        type: `Characters`,
        content: nodeContent,
        contentDigest: createContentDigest(character),
      },
    }
    const node = Object.assign({}, character, nodeMeta)
    createNode(node)
  })
}

Gatsby 的 createPages API 可能是您正在寻找的。

我用它创建了多个页面,例如 blog1、blog2、blog3 等... 同样,您可以为您的角色创建多个页面。

既然你提到你有一个 graphql 调用来让你的角色使用

const pages = await graphql(`
 query CharactersQuery {
    allCharacters(limit: 5) {
      edges {
        node {
          id
          name
          status
          gender
          image
        }
      }
    }
  }
`)

上面的 graphql 调用 returns 结果是 pages.data.allCharacters.edges

现在您可以使用 foreach 迭代它们并使用 createPage 创建页面。

以下是您可能需要添加到 gatsby-node.js 文件中的完整模拟代码

    const path = require('path');

    exports.createPages = async ({ graphql, actions }) => {
      const { createPage } = actions
      const templateOfYourCharacterPage = path.resolve(`src/templates/exampleTemplateFile.jsx`)

    const pages = await graphql(`
     query CharactersQuery {
        allCharacters(limit: 5) {
          edges {
            node {
              id
              name
              status
              gender
              image
            }
          }
        }
      }
    `)

      let characters = pages.data.allCharacters.edges;

      characters.forEach(edge => {
        createPage({
          path: `/${edge.node.id}`,
          component: templateOfYourCharacterPage,
          context: {id: edge.node.uid, name: edge.node.name } // This is to pass data as props to your component.
        })
      })

    }