无法映射到React中的查询

时间:2020-04-05 18:29:51

标签: reactjs graphql apollo

我将Apollo与React一起使用,以映射查询,但出现TypeError:无法读取未定义的属性'map'。

我不知道道具传递是问题还是查询本身...

我知道查询是由片段组成的,但是更改该剂量不能解决错误。

代码如下:

App.js

import React from 'react';
import './App.css';

import { Query } from 'react-apollo'
import { gql } from  'apollo-boost'

import ListPosts from './components/ListPosts'

function App() {
  return (
    <Query query={GET_POSTS_QUERY}>
      {(data, loading, error) => {
        if (loading) return <div>loading</div>
        if (error) return <div>error</div>

        return <ListPosts posts={data.allPosts} />

      }}
    </Query>
  )
}

const GET_POSTS_QUERY = gql`
{
  allPosts {
    ... on PostType {
      title
      createdAt
      content
      postImage
      postedBy {
        username
      }
    }
    ... on Post2Type {
      title
      createdAt
      content
      postImage
      postedBy {
        username
      }
    }
  }
}

`

export default App;

ListPosts.js

import React from "react";

const ListPosts = ({ posts }) => (
    <div>
        {posts.map(post => (
            <div key={post.id}>
                <h1>{post.title}</h1>
            </div>
        ))}
    </div>
)

export default ListPosts;

有关更多上下文,这是JSON中的响应

{
  "data": {
    "allPosts": [
      {
        "title": "vesti",
        "createdAt": "2020-04-05T12:37:09.451520+00:00",
        "content": "<p><strong>asdasda</strong></p>",
        "postImage": "post/logo.png",
        "postedBy": {
          "username": "filip"
        }
      },
      {
        "title": "asds",
        "createdAt": "2020-04-05T17:44:11.291829+00:00",
        "content": "<p>asdasd</p>",
        "postImage": "",
        "postedBy": {
          "username": "filip"
        }
      }
    ]

谢谢!

3 个答案:

答案 0 :(得分:2)

Query Render prop function

您传递给children的{​​{1}} prop的render prop函数 被调用的对象(Query)具有以下内容 属性。该对象包含您的查询结果,以及一些有用的信息 重新提取,动态轮询和分页的功能。

换句话说,渲染道具是具有所需属性的道具对象。该组件也只传递了一个参数。

整个QueryResult被分配给名为props的变量,并且由于dataloading未定义(即错误),因此这些条件测试失败,您尝试渲染帖子。现在,error或实际上data.allPosts不存在。

使用对象解构,您可以访问props.allPostsdataloading道具。

error

答案 1 :(得分:1)

1。您在JSON中的响应不是完整的JSON应该是这样的:

{
  data: {
    allPosts: [
      {
        title: "vesti",
        createdAt: "2020-04-05T12:37:09.451520+00:00",
        content: "<p><strong>asdasda</strong></p>",
        postImage: "post/logo.png",
        postedBy: {
          username: "filip"
        }
      },
      {
        title: "asds",
        createdAt: "2020-04-05T17:44:11.291829+00:00",
        content: "<p>asdasd</p>",
        postImage: "",
        postedBy: {
          username: "filip"
        }
      }
    ]
  }
}

2。您要发送的data.allpost不应该是驼峰式的,所以当您在ListPost中将它作为道具接收时,您不应将其包装在对象中:

const ListPosts = (posts) => (...)

3。如果要映射对象,则必须通过Object.entries()或Object.values()访问对象内的数组,因此:

Object.entries(posts).map(postArray => (...)

将返回[posts :, [array(2)]]

4。现在您可以访问数组了,您将需要像对其一样进行映射:

 postArray[1].map(post => {
 return(
  <div key={post.title}>
          <div style={{ borderStyle: "solid" }}>
            <h3>{post.title}</h3>
          </div>
          <div style={{ borderStyle: "solid", borderWidth: "2px" }}>
            <p>{post.createdAt}</p>
            <p>{post.content}</p>
            <p>{post.postImage}</p>
            <p>{post.postedBy.username}</p>
          </div>
  </div>
  )}

我为您创建了一个示例供您更好地了解:https://codesandbox.io/s/component-drilling-props-grxm4

检查控制台,您将能够查看日志

希望这可以帮助您好运!

答案 2 :(得分:0)

import React from "react";

const ListPosts = props => {
  return (
    <div>
      {
        props.posts.map(post => {
          <div key={post.id}>
            <h1>{post.title}</h1>
          </div>
        });
      }
    </div>
  );
};

export default ListPosts;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

import React from "react";

const ListPosts = props => (
<div>
    {props.posts.map(post => (
        <div key={post.id}>
            <h1>{post.title}</h1>
        </div>
    ))}
</div>
)

export default ListPosts;

您可以进行这些更改吗?