Apollo GraphQL 解构数据不起作用
Apollo GraphQL Deconstruction of data not working
我正在挖掘 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 }
来解构 returned 数据。但是在我的代码中,我遵循了它但是我得到了一个错误
TypeError: Cannot read property 'getPosts' of undefined
相反,如果我像下面这样编码,
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 nextjs
、2. my code is on apollo-server-express
。其他事情几乎相同,我的解析器使用 async/await
,并将 return 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)
}
},
您的教程可能已过时。在旧版本的 Apollo Client 中,data
最初设置为一个空对象。这样,如果您的代码访问了其中的一些 属性,它就不会崩溃。虽然这很方便,但也不是特别准确(没有数据,所以我们为什么要提供一个对象?)。现在, data
只是未定义,直到您的操作完成。这就是后一个代码起作用的原因——在 loading
为 false 之前,您不会访问数据的任何属性,这意味着查询已完成并且 data
不再是未定义的。
如果您想在声明钩子时解构 data
,您可以使用这样的默认值:
const {
loading,
data: { getPosts: posts } = {}
} = useQuery(FETCH_POSTS_QUERY)
如果您愿意,您甚至可以为 posts
分配一个默认值。
请记住另外两件事:第一,即使在 loading
更改为 true
,因此请确保您的代码考虑到了这种情况。第二,根据您的架构,如果您的响应中有 errors
,则您的整个 data
对象可能最终为空。在这种情况下,你会仍然遇到解构问题,因为默认值只适用于未定义的,而不适用于空值。
我正在挖掘 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 }
来解构 returned 数据。但是在我的代码中,我遵循了它但是我得到了一个错误
TypeError: Cannot read property 'getPosts' of undefined
相反,如果我像下面这样编码,
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 nextjs
、2. my code is on apollo-server-express
。其他事情几乎相同,我的解析器使用 async/await
,并将 return 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)
}
},
您的教程可能已过时。在旧版本的 Apollo Client 中,data
最初设置为一个空对象。这样,如果您的代码访问了其中的一些 属性,它就不会崩溃。虽然这很方便,但也不是特别准确(没有数据,所以我们为什么要提供一个对象?)。现在, data
只是未定义,直到您的操作完成。这就是后一个代码起作用的原因——在 loading
为 false 之前,您不会访问数据的任何属性,这意味着查询已完成并且 data
不再是未定义的。
如果您想在声明钩子时解构 data
,您可以使用这样的默认值:
const {
loading,
data: { getPosts: posts } = {}
} = useQuery(FETCH_POSTS_QUERY)
如果您愿意,您甚至可以为 posts
分配一个默认值。
请记住另外两件事:第一,即使在 loading
更改为 true
,因此请确保您的代码考虑到了这种情况。第二,根据您的架构,如果您的响应中有 errors
,则您的整个 data
对象可能最终为空。在这种情况下,你会仍然遇到解构问题,因为默认值只适用于未定义的,而不适用于空值。