Apollo GraphQL 加载查询

Posted

技术标签:

【中文标题】Apollo GraphQL 加载查询【英文标题】:Apollo GraphQL loading query 【发布时间】:2020-10-01 09:28:00 【问题描述】:

我正在使用 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;

然后它会获取一个单独的帖子

    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 不是函数。

【问题讨论】:

【参考方案1】:

当你使用useQuery时,你不应该像result.data.posts.nodes那样解构数据,因为数据字段将是undefinedloading第一次调用时为真。这就是您收到错误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>
  );
;

【讨论】:

我已经修改了我的答案,我不确定如何解决单个帖子页面。 @HeyImArt 您可以使用相同的方式处理获取单个帖子页面的数据。 所以我移动了那些变量,而不是初始属性,并将加载、错误和数据传递给新的 useQuery,然后返回帖子? @HeyImArt 您可以在组件中使用useQuery 并将postID 作为其变量来获取帖子数据。 对不起,迈克尔,我对这一切还很陌生——我无法让它工作。我尝试将它移动到组件中,然后将该组件调用到 中的页面中,但它现在什么也不呈现。

以上是关于Apollo GraphQL 加载查询的主要内容,如果未能解决你的问题,请参考以下文章

Apollo GraphQL 加载查询

Graphql,react-apollo如何在加载组件状态时将变量传递给查询

Angular Apollo 将 URI 注入 graphql.module.ts

Apollo Graphql:避免在重新获取期间加载指示器

Vuex 状态随突变而变化 - apollo graphql 查询

将 Apollo 客户端用于 GraphQl 时如何在 watchQuery 中使用 loading 属性