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

时间:2019-08-08 16:46:47

标签: javascript reactjs graphql gatsby

这是与this类似的问题。

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

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

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

让我迷失的是我希望能够使用每个页面的网址characters/<characterIdHere>为每个字符创建一个页面。我知道我需要在gatsby-node.js文件(..?的主版本或插件版本)中添加一些逻辑,但这是我要坚持的部分。我不知道需要将什么放入gatsby-node.js文件中。这些示例我可以找到所有使用json或markdown文件的示例,并且我想使用从API中提取的数据到盖茨比的数据层。很明显,我已经研究了几个小时,并在询问之前进行了尝试,但是没有任何运气。

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

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)
  })
}

1 个答案:

答案 0 :(得分:2)

您可能正在寻找加茨比(Gatsby)的createPages API。

我用它来创建多个页面,例如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.
        })
      })

    }