GatsbyJS 从 Restful API 获取数据

GatsbyJS getting data from Restful API

我是 React 和 GatsbyJS 的新手。我很困惑,无法弄清楚从第三方加载数据的简单方法 Restful API。

比如我想从randomuser中获取数据。me/API然后可以在页面中使用这些数据。

让我们这样说吧:

  import React from 'react'
  import Link from 'gatsby-link'

  class User extends React.Component {
    constructor(){
      super();
      this.state = {
        pictures:[],
      };

    }

    componentDidMount(){
      fetch('https://randomuser.me/api/?results=500')
      .then(results=>{
        return results.json();
      })
      .then(data=>{
        let pictures = data.results.map((pic,i)=>{
            return(
              <div key={i} >
                <img key={i} src={pic.picture.medium}/>
              </div>
            )
        })
        this.setState({pictures:pictures})
      })
    }

    render() {
      return (<div>{this.state.pictures}</div>)
    }
  }

  export default User;

但我想得到 GraphQL 的帮助,以便对用户进行过滤和排序等......

能否请您帮我找到有关如何获取数据并将其插入 gatsby-node.js 上的 GraphQL 的示例?

如果你想使用 GraphQL 来获取你的数据,你必须创建一个 sourceNode。关于 creating a source plugin 的文档可以帮助您。

按照这些步骤可以在您的 Gatsby 项目中使用 GraphQL 查询 randomuser 数据。

1) 在gatsby-node.js

中创建节点

在您的根项目文件夹中,将此代码添加到 gatsby-node.js:

const axios = require('axios');
const crypto = require('crypto');

exports.sourceNodes = async ({ actions }) => {
  const { createNode } = actions;

  // fetch raw data from the randomuser api
  const fetchRandomUser = () => axios.get(`https://randomuser.me/api/?results=500`);
  // await for results
  const res = await fetchRandomUser();

  // map into these results and create nodes
  res.data.results.map((user, i) => {
    // Create your node object
    const userNode = {
      // Required fields
      id: `${i}`,
      parent: `__SOURCE__`,
      internal: {
        type: `RandomUser`, // name of the graphQL query --> allRandomUser {}
        // contentDigest will be added just after
        // but it is required
      },
      children: [],

      // Other fields that you want to query with graphQl
      gender: user.gender,
      name: {
        title: user.name.title,
        first: user.name.first,
        last: user.name.last,
      },
      picture: {
        large: user.picture.large,
        medium: user.picture.medium,
        thumbnail: user.picture.thumbnail,
      }
      // etc...
    }

    // Get content digest of node. (Required field)
    const contentDigest = crypto
      .createHash(`md5`)
      .update(JSON.stringify(userNode))
      .digest(`hex`);
    // add it to userNode
    userNode.internal.contentDigest = contentDigest;

    // Create node with the gatsby createNode() API
    createNode(userNode);
  });

  return;
}

I used axios to fetch data so you will need to install it: npm install --save axios

解释:

目标是为要使用的每条数据创建每个节点。 根据 createNode documentation,您必须提供一个具有少量必填字段(id、parent、internal、children)的对象。

从随机用户 API 获得结果数据后,您只需创建此节点对象并将其传递给 createNode() 函数。

这里我们映射到你想要获得 500 个随机用户的结果 https://randomuser.me/api/?results=500

创建 userNode 包含必填字段和所需字段的对象。 您可以根据要在应用中使用的数据添加更多字段。

只需使用 Gatsby API 的 createNode() 函数创建节点即可。

2) 使用 GraphQL 查询数据

完成后,运行 gatsby develop 并转到 http://localhost:8000/___graphql

您可以使用 GraphQL 来创建完美的查询。由于我们将节点对象的 internal.type 命名为 'RandomUser',我们可以查询 allRandomUser 来获取我们的数据。

{
  allRandomUser {
    edges {
      node {
        gender
        name {
          title
          first
          last
        }
        picture {
          large
          medium
          thumbnail
        }
      }
    }
  }
}

3) 在您的 Gatsby 页面中使用此查询

在您的页面中,例如 src/pages/index.js,使用查询并显示您的数据:

import React from 'react'
import Link from 'gatsby-link'

const IndexPage = (props) => {
  const users = props.data.allRandomUser.edges;

  return (
    <div>
      {users.map((user, i) => {
        const userData = user.node;
        return (
          <div key={i}>
            <p>Name: {userData.name.first}</p>
            <img src={userData.picture.medium} />
          </div>
        )
      })}
    </div>
  );
};

export default IndexPage

export const query = graphql`
  query RandomUserQuery {
    allRandomUser {
      edges {
        node {
          gender
          name {
            title
            first
            last
          }
          picture {
            large
            medium
            thumbnail
          }
        }
      }
    }
  }
`;

就是这样!

非常感谢,这对我来说工作正常,我只更改了 gastbyjs-node.js 的一小部分,因为在使用同步和等待时它会出错,我想我需要更改构建的某些部分使用 babel 的过程允许我使用 sync 或 await。

这是适合我的代码。

 const axios = require('axios');
 const crypto = require('crypto');

 // exports.sourceNodes = async ({ boundActionCreators }) => {
 exports.sourceNodes = ({boundActionCreators}) => {
const {createNode} = boundActionCreators;
return new Promise((resolve, reject) => {

// fetch raw data from the randomuser api
// const fetchRandomUser = () => axios.get(`https://randomuser.me/api/?results=500`);
// await for results
// const res = await fetchRandomUser();

axios.get(`https://randomuser.me/api/?results=500`).then(res => {

  // map into these results and create nodes
  res.data.results.map((user, i) => {

    // Create your node object
    const userNode = {
      // Required fields
      id: `${i}`,
      parent: `__SOURCE__`,
      internal: {
        type: `RandomUser`, // name of the graphQL query --> allRandomUser {}
        // contentDigest will be added just after
        // but it is required
      },
      children: [],

      // Other fields that you want to query with graphQl
      gender: user.gender,
      name: {
        title: user.name.title,
        first: user.name.first,
        last: user.name.last
      },
      picture: {
        large: user.picture.large,
        medium: user.picture.medium,
        thumbnail: user.picture.thumbnail
      }
      // etc...
    }

    // Get content digest of node. (Required field)
    const contentDigest = crypto.createHash(`md5`).update(JSON.stringify(userNode)).digest(`hex`);
    // add it to userNode
    userNode.internal.contentDigest = contentDigest;

    // Create node with the gatsby createNode() API
    createNode(userNode);
  });
  resolve();
});

});

}

上面给出的答案有效,除了第 2 步中的查询对我来说似乎只有 return 一个节点。我可以通过将 totalCount 添加为边的同级来 return 所有节点。 IE。

{
  allRandomUser {
    totalCount
    edges {
      node {
        id
        gender
        name {
          first
          last
        }
      }
    }
  }
}

公认的答案非常有效,只是要注意,如果您使用 boundActionCreators,则会出现弃用警告。这必须重命名为 actions 以避免出现此警告。

您可以使用 React useEffect 从 API 的前端获取数据。它运行完美,你将不再在 buildtime

看到任何错误
 const [starsCount, setStarsCount] = useState(0)
  useEffect(() => {
    // get data from GitHub api
    fetch(`https://api.github.com/repos/gatsbyjs/gatsby`)
      .then(response => response.json()) // parse JSON from request
      .then(resultData => {
        setStarsCount(resultData.stargazers_count)
      }) // set data for the number of stars
  }, [])