Graphql 查询在 graphql 服务器上运行良好,但在客户端上则不然



我有一个解析器来检查用户登录与否

// ______________________________Check if user logged in____________________________________
@Query((_return) => User, { nullable: true })
async user(@Ctx() { req }: Context): Promise<User | null | undefined> {
console.log(req.session.userId)
if (!req.session.userId) return null;
else{
return await User.findOne(req.session.userId)
}
}

它可以在 http://localhost:4000/graphql 上工作,但是当我在客户端(React)上查询时,它返回未定义。

客户端查询代码

const { data, loading, error } = useUserQuery();
console.log(`data:${data}`)
console.log(`error:${error}`)

我使用 codegen 生成 useUserQuery(),它就像

export function useUserQuery(baseOptions?: Apollo.QueryHookOptions<UserQuery, UserQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<UserQuery, UserQueryVariables>(UserDocument, options);
}

我在客户端上的cookie仍然存在,但它不起作用,我该如何解决?

您的 Apollo 查询需要有限的时间才能返回答案;这就是为什么当您立即登录${data}时,您会得到undefined

您可以通过注销loading变量来确认这一点 - 您将看到它true- 查询"正在进行中",data将继续undefined,直到loading变为 false。

因此,处理此问题的一种非常简单的方法可能就像这个 Apollo 文档示例一样 - 只需在我们loading时尽早返回:

const { data, loading, error } = useUserQuery();
if (loading) return 'Loading...';
// At this point we either have an error or data; handle it
console.log(`data:${data}`)
console.log(`error:${error}`)

如果你有能力在数据到达之前"停止世界"(或至少是UI),那很好,但通常我喜欢尽可能多地渲染并用useEffect()"听"data,然后你可以在它可用后做一些事情:

const { data, error } = useUserQuery();
useEffect(() => {
// Always check for an error first:
if (error) {
console.log(`error:${error}`)
}

if (data) {
// Handle the data
console.log(`data:${data}`)
}
}, [data, error]);
...
// Always return the UI
return (
...
);

最新更新