首页 > 解决方案 > Apollo GraphQL 加载查询

问题描述

我正在使用 Apollo GraphQL 来获取帖子以填充下一个 js 项目。

我目前拥有的代码有效,但我想实现 useQuery 的加载状态,而不是下面的代码。

这是索引(如果您愿意,可以发布页面)

import Layout from "../components/Layout";
import Post from "../components/Post";
import client from "./../components/ApolloClient";
import gql from "graphql-tag";

const POSTS_QUERY = gql`
  query {
    posts {
      nodes {
        title
        slug
        postId
        featuredImage {
          sourceUrl
        }
      }
    }
  }
`;

const Index = props => {
  const { posts } = props;

  return (
    <Layout>
      <div className="container">
        <div className="grid">
          {posts.length
            ? posts.map(post => <Post key={post.postId} post={post} />)
            : ""}
        </div>
      </div>
    </Layout>
  );
};

Index.getInitialProps = async () => {
  const result = await client.query({ query: POSTS_QUERY });

  return {
    posts: result.data.posts.nodes
  };
};

export default Index;

然后它获取一个单独的 Post

    import Layout from "../components/Layout";
import { withRouter } from "next/router";
import client from "../components/ApolloClient";

import POST_BY_ID_QUERY from "../queries/post-by-id";

const Post = withRouter(props => {
  const { post } = props;

  return (
    <Layout>
      {post ? (
        <div className="container">
          <div className="post">
            <div className="media">
              <img src={post.featuredImage.sourceUrl} alt={post.title} />
            </div>
            <h2>{post.title}</h2>
          </div>
        </div>
      ) : (
        ""
      )}
    </Layout>
  );
});

Post.getInitialProps = async function(context) {
  let {
    query: { slug }
  } = context;
  const id = slug ? parseInt(slug.split("-").pop()) : context.query.id;
  const res = await client.query({
    query: POST_BY_ID_QUERY,
    variables: { id }
  });

  return {
    post: res.data.post
  };
};

export default Post;

每当我尝试将 useQuery 与 '@apollo/react-hooks' 一起使用时,我总是会得到一个 data.posts.map 不是函数。

标签: next.jsapolloapollo-client

解决方案


当你使用 时useQuery,你不应该像这样解构数据,result.data.posts.nodes因为数据字段将是undefined并且loading是第一次调用时为真。这就是为什么你得到一个错误data.posts.map is not a function。然后,如果您的查询成功获取数据,则该loading字段将为 false。
你可以试试:

import Layout from "../components/Layout";
import Post from "../components/Post";
import client from "./../components/ApolloClient";
import { useQuery } from "@apollo/react-hooks"
import gql from "graphql-tag";

const POSTS_QUERY = gql`
  query {
    posts {
      nodes {
        title
        slug
        postId
        featuredImage {
          sourceUrl
        }
      }
    }
  }
`;

const Index = props => {
  const { posts } = props;
  const { loading, error, data } = useQuery(POSTS_QUERY);
  
  if (loading) return <div>Loading...</div>
  if (error) return <div>Error</div>
  
  return (
    <Layout>
      <div className="container">
        <div className="grid">
          {data.posts.nodes.length
            ? data.posts.nodes.map(post => <Post key={post.postId} post={post} />)
            : ""}
        </div>
      </div>
    </Layout>
  );
};


推荐阅读