【问题标题】:Programmatically create Gatsby pages from API data以编程方式从 API 数据创建 Gatsby 页面
【发布时间】:2019-12-16 10:35:21
【问题描述】:

这是一个与this类似的问题。

我正在寻求使用 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)
  })
}

【问题讨论】:

    标签: javascript reactjs graphql gatsby


    【解决方案1】:

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

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

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

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

    上面的graphql调用返回结果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.
            })
          })
    
        }
    

    【讨论】:

      猜你喜欢
      • 2018-06-23
      • 2020-04-29
      • 1970-01-01
      • 2021-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-16
      相关资源
      最近更新 更多