我将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"
}
}
]
谢谢!
答案 0 :(得分:2)
Query
Render prop function
您传递给
children
的{{1}} prop的render prop函数 被调用的对象(Query
)具有以下内容 属性。该对象包含您的查询结果,以及一些有用的信息 重新提取,动态轮询和分页的功能。
换句话说,渲染道具是具有所需属性的道具对象。该组件也只传递了一个参数。
整个QueryResult
被分配给名为props
的变量,并且由于data
和loading
未定义(即错误),因此这些条件测试失败,您尝试渲染帖子。现在,error
或实际上data.allPosts
不存在。
使用对象解构,您可以访问props.allPosts
,data
和loading
道具。
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;
您可以进行这些更改吗?