Apollo GraphQL 数据解构不起作用

Posted

技术标签:

【中文标题】Apollo GraphQL 数据解构不起作用【英文标题】:Apollo GraphQL Deconstruction of data not working 【发布时间】:2020-07-15 11:35:19 【问题描述】:

我正在挖掘graphql,所以我遵循了一个教程,我坚持在这一部分。

Home.js

function Home() 
  const 
    loading,
    data:  getPosts: posts    // <===## Here ##
   = useQuery(FETCH_POSTS_QUERY);

  return (
      <div>
        loading ? (
          <h1>Loading posts..</h1>
        ) : (
          posts &&
          posts.map((post) => (
            <p>
              post.content
            </p>
          ))
        )
      </div>
  );


const FETCH_POSTS_QUERY = gql`
  
    getPosts 
      id
      content
    
  
`;


export default Home;

解析器

  Query: 
    async getPosts() 
      try 
        const posts = await Post.find().sort( createdAt: -1 );
        return posts;
       catch (err) 
        throw new Error(err);
      
    
  ,

完整代码:https://github.com/hidjou/classsed-graphql-mern-apollo/tree/react10

在上面的例子中运行良好,它使用data: getPosts: posts 来解构返回的数据。但是在我的代码中,我遵循了它,但出现了错误

TypeError:无法读取未定义的属性“getPosts”

相反,如果我像下面这样编码,

function Home() 
  const 
    loading,
    data // <===## Here ##
   = useQuery(FETCH_POSTS_QUERY);

  if(loading) return <h1>Loading...</h1>

  const  getPosts: posts  = data // <===## Here ##

  return (
      <div>
        loading ? (
          <h1>Loading posts..</h1>
        ) : (
          posts &&
          posts.map((post) => (
            <p>
              post.content
            </p>
          ))
        )
      </div>
  );

它运作良好。似乎我的代码在加载之前尝试引用data。但我不知道为什么会这样。代码几乎相同。不同的东西是1. my code is on nextjs2. my code is on apollo-server-express。其他几乎相同,我的解析器使用async/await,并将返回posts。我错过了什么吗?

我的解析器如下所示。

 Query: 
    async getPosts(_,  pageNum, searchQuery ) 
      try 
        const perPage = 5
        const posts =
          await Post
            .find(searchQuery ?  $or: search  : )
            .sort('-_id')
            .limit(perPage)
            .skip((pageNum - 1) * perPage)
        return posts
       catch (err) 
        throw new Error(err)
      
    ,

【问题讨论】:

【参考方案1】:

您的教程可能已过时。在旧版本的 Apollo Client 中,data 最初设置为空对象。这样,如果您的代码访问了它上面的某些属性,它就不会崩溃。虽然这很方便,但也不是特别准确(没有数据,我们为什么要提供对象?)。现在,data 在您的操作完成之前是未定义的。这就是后一个代码起作用的原因——在loading 为假之前,您不能访问数据的任何属性,这意味着查询已完成并且data 不再未定义。

如果你想在你的钩子被声明时解构data,你可以使用这样的默认值:

const 
  loading,
  data:  getPosts: posts  = 
 = useQuery(FETCH_POSTS_QUERY)

如果您愿意,您甚至可以为 posts 指定一个默认值。

请记住另外两件事:第一,如果发生网络错误,data保持未定义,即使在将 loading 更改为 true 之后,因此请确保您的代码帐户对于这种情况。第二,根据您的架构,如果您的响应中有errors,则您的整个data 对象可能最终为空。在这种情况下,您仍然会遇到解构问题,因为默认值仅适用于 undefined,而不适用于 null。

【讨论】:

以上是关于Apollo GraphQL 数据解构不起作用的主要内容,如果未能解决你的问题,请参考以下文章

APOLLO CLIENT - 突变不起作用(无法读取未定义的属性“数据”)

带有 Express(JS) 的后端 - GraphQL 变异函数不起作用

Apollo 服务器订阅不起作用

使用 ApolloClient 将变量传递给 GraphQL 突变似乎不起作用

Graphql - Apollo 服务器 - 热更新模式

为啥“自动商店更新”在反应应用程序的客户端商店中不起作用?