useQuery 的奇怪问题:未读取查询参数
Strange issue with useQuery: Query arguments not being read
我有一个组件将字符串 (userToFetch
) 作为参数化查询中的可变参数传递。该组件如下所示:
// pages/index.jsx
import React from 'react';
import { useQuery } from '@apollo/react-hooks';
import gql from 'graphql-tag';
const GET_USERS = gql`
query users ($limit: Int!, $username: String!) {
users (limit: $limit, where: { username: $username }) {
username
firstName
}
}
`;
const Home = () => {
const userToFetch = 'jonsnow';
const {
loading,
error,
data,
} = useQuery(
GET_USERS,
{
variables: { limit: 2, username: userToFetch },
notifyOnNetworkStatusChange: true,
},
);
if (loading) {
return <p>Loading...</p>;
}
if (error) {
return <p>Error: {JSON.stringify(error)}</p>;
}
return (
<div>
<ul>
{data.users.map(user => {
return <li>{user.username} {user.firstName}</li>;
})}
</ul>
</div>
);
};
export default Home;
这就是我配置 Apollo 客户端的方式:
// /apollo-client.js
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import withApollo from 'next-with-apollo';
import { createHttpLink } from 'apollo-link-http';
import fetch from 'isomorphic-unfetch';
const GRAPHQL_URL = 'https://dev.schandillia.com/graphql';
const link = createHttpLink({
fetch, // Switches between unfetch & node-fetch for client & server.
uri: GRAPHQL_URL
});
// Export a HOC from next-with-apollo
// Docs: https://www.npmjs.com/package/next-with-apollo
export default withApollo(
// You can get headers and ctx (context) from the callback params
// e.g. ({ headers, ctx, initialState })
({ initialState, ctx }) => {
console.log('initialState', initialState);
console.log('ctx', ctx);
return new ApolloClient({
link: link,
cache: new InMemoryCache()
// rehydrate the cache using the initial data passed from the server:
.restore(initialState || {})
})
}
);
数据库是以下users
的集合:
"users": [
{
"username": "negger",
"firstName": "Arnold",
"lastName": "Schwarzenegger"
},
{
"username": "jonsnow",
"firstName": "Jon",
"lastName": "Snow"
},
{
"username": "tonystark",
"firstName": "Tony",
"lastName": "Stark"
}
]
}
现在,虽然这应该可以工作(当我 运行 在我的 graphql 游乐场 https://dev.schandillia.com/graphql 查询时它会工作),代码 运行s 就好像 where
子句不存在!它只是 returns 所有结果,就好像 运行 的查询是:
users {
_id
username
firstName
}
要重现问题,请访问 https://www.schandillia.com。该页面应该显示一个列表,其中只有一个元素由匹配的 username-firstName 值组成:jonsnow Jon
但它 returns 两个条目,negger Arnold
和 jonsnow Jon
(重新指定 limit
但完全忽略 where
)。现在,运行 与 jonsnow
相同的查询作为 https://dev.schandillia.com/graphql 中的 where
参数:
{
users(where: { username: "jonsnow" }) {
_id
username
firstName
}
}
而且结果完全符合预期:
{
"data": {
"users": [
{
"_id": "5d9f261678a32159e61018fc",
"username": "jonsnow",
"firstName": "Jon",
}
]
}
}
我忽略了什么?
P.S.: 仓库在 https://github.com/amitschandillia/proost/tree/master/apollo-nextjs.
供参考
更新:为了追查根本原因,我尝试在 apollo-client.js
:
中记录一些值
console.log('initialState', initialState);
奇怪的是,输出显示了正确的查询,以及传递的变量,但结果是错误的:
...
ROOT_QUERY.users({"limit":2,"where":{"username":"jonsnow"}}).0:
firstName: "Arnold"
username: "negger"
__typename: "UsersPermissionsUser"
...
更新:这是我的 Apollo 客户端开发工具中结果的屏幕截图:
Strapi 生成的模式为 where 属性提供了一个类型 JSON,因此您必须将查询变量中的整个 where 部分作为 JSON 传递,因为变量没有被注入。
# Write your query or mutation here
query users($where: JSON) {
users(where: $where) {
username
firstName
}
}
变量看起来像:
{"where": {"username": "jonsnow"}}
我有一个组件将字符串 (userToFetch
) 作为参数化查询中的可变参数传递。该组件如下所示:
// pages/index.jsx
import React from 'react';
import { useQuery } from '@apollo/react-hooks';
import gql from 'graphql-tag';
const GET_USERS = gql`
query users ($limit: Int!, $username: String!) {
users (limit: $limit, where: { username: $username }) {
username
firstName
}
}
`;
const Home = () => {
const userToFetch = 'jonsnow';
const {
loading,
error,
data,
} = useQuery(
GET_USERS,
{
variables: { limit: 2, username: userToFetch },
notifyOnNetworkStatusChange: true,
},
);
if (loading) {
return <p>Loading...</p>;
}
if (error) {
return <p>Error: {JSON.stringify(error)}</p>;
}
return (
<div>
<ul>
{data.users.map(user => {
return <li>{user.username} {user.firstName}</li>;
})}
</ul>
</div>
);
};
export default Home;
这就是我配置 Apollo 客户端的方式:
// /apollo-client.js
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import withApollo from 'next-with-apollo';
import { createHttpLink } from 'apollo-link-http';
import fetch from 'isomorphic-unfetch';
const GRAPHQL_URL = 'https://dev.schandillia.com/graphql';
const link = createHttpLink({
fetch, // Switches between unfetch & node-fetch for client & server.
uri: GRAPHQL_URL
});
// Export a HOC from next-with-apollo
// Docs: https://www.npmjs.com/package/next-with-apollo
export default withApollo(
// You can get headers and ctx (context) from the callback params
// e.g. ({ headers, ctx, initialState })
({ initialState, ctx }) => {
console.log('initialState', initialState);
console.log('ctx', ctx);
return new ApolloClient({
link: link,
cache: new InMemoryCache()
// rehydrate the cache using the initial data passed from the server:
.restore(initialState || {})
})
}
);
数据库是以下users
的集合:
"users": [
{
"username": "negger",
"firstName": "Arnold",
"lastName": "Schwarzenegger"
},
{
"username": "jonsnow",
"firstName": "Jon",
"lastName": "Snow"
},
{
"username": "tonystark",
"firstName": "Tony",
"lastName": "Stark"
}
]
}
现在,虽然这应该可以工作(当我 运行 在我的 graphql 游乐场 https://dev.schandillia.com/graphql 查询时它会工作),代码 运行s 就好像 where
子句不存在!它只是 returns 所有结果,就好像 运行 的查询是:
users {
_id
username
firstName
}
要重现问题,请访问 https://www.schandillia.com。该页面应该显示一个列表,其中只有一个元素由匹配的 username-firstName 值组成:jonsnow Jon
但它 returns 两个条目,negger Arnold
和 jonsnow Jon
(重新指定 limit
但完全忽略 where
)。现在,运行 与 jonsnow
相同的查询作为 https://dev.schandillia.com/graphql 中的 where
参数:
{
users(where: { username: "jonsnow" }) {
_id
username
firstName
}
}
而且结果完全符合预期:
{
"data": {
"users": [
{
"_id": "5d9f261678a32159e61018fc",
"username": "jonsnow",
"firstName": "Jon",
}
]
}
}
我忽略了什么?
P.S.: 仓库在 https://github.com/amitschandillia/proost/tree/master/apollo-nextjs.
供参考更新:为了追查根本原因,我尝试在 apollo-client.js
:
console.log('initialState', initialState);
奇怪的是,输出显示了正确的查询,以及传递的变量,但结果是错误的:
...
ROOT_QUERY.users({"limit":2,"where":{"username":"jonsnow"}}).0:
firstName: "Arnold"
username: "negger"
__typename: "UsersPermissionsUser"
...
更新:这是我的 Apollo 客户端开发工具中结果的屏幕截图:
Strapi 生成的模式为 where 属性提供了一个类型 JSON,因此您必须将查询变量中的整个 where 部分作为 JSON 传递,因为变量没有被注入。
# Write your query or mutation here
query users($where: JSON) {
users(where: $where) {
username
firstName
}
}
变量看起来像:
{"where": {"username": "jonsnow"}}