Apollo 客户端没有读取使用 useQuery 钩子传入的变量

Posted

技术标签:

【中文标题】Apollo 客户端没有读取使用 useQuery 钩子传入的变量【英文标题】:Apollo Client is not reading variables passed in using useQuery hook 【发布时间】:2020-05-28 13:44:08 【问题描述】:

将变量传递到 useQuery 挂钩时遇到一个奇怪的问题。

查询:

const GET_USER_BY_ID= gql`
  query($id: ID!) 
    getUser(id: $id) 
      id
      fullName
      role
    
  
`;

调用查询:

const DisplayUser: React.FC< id: string > = ( id ) => 
  const  data, error  = useQuery(GET_USER_BY_ID, 
    variables:  id ,
  );

  return <div>JSON.stringify( data, error )</div>;
;

渲染组件:

<DisplayUser id="5e404fa72b819d1410a3164c" />

这会产生错误:

"Argument \"id\" of required type \"ID!\" was provided the variable \"$id\" which was not provided a runtime value."

从 GraphQL Playground 调用查询返回预期结果:


  "data": 
    "getUser": 
      "id": "5e404fa72b819d1410a3164c",
      "fullName": "Test 1",
      "role": "USER"
    
  

并在没有变量的情况下调用查询,而是对 id 进行硬编码:

const GET_USER_BY_ID = gql`
  query 
    getUser(id: "5e404fa72b819d1410a3164c") 
      id
      fullName
      role
    
  
`;

const DisplayUser: React.FC = () => 
  const  data, error  = useQuery(GET_USER_BY_ID);

  return <div>JSON.stringify( data, error )</div>;
;

也返回预期的结果。

我还尝试测试一个类似的查询,该查询将firstName: String! 作为参数,它也会产生一个错误,指出没有为变量提供运行时值。在对查询字符串中的值进行硬编码时,此查询也可以正常工作。

这个项目今天开始,使用"apollo-boost": "^0.4.7""graphql": "^14.6.0""react-apollo": "^3.1.3"

【问题讨论】:

那个钩子看起来是正确的,所以我怀疑它要么是react-apollo 的错误,要么是你的代码发生了其他事情。如果将id的值记录到组件内部的控制台,是否定义了? 是的,没错,id 按预期记录。 在 Playground 版本中使用变量进行测试...在 query 之后使用名称 User 检查:query User($id: ID!) getUser .... @xadm 嗯,它也不喜欢那里的变量。我想这意味着这是我的服务器的问题?我正在运行 typeorm 和 type-graphql。 playground/docs如何定义ID类型? 【参考方案1】:

试试

const  data, error  = useQuery(GET_USER_BY_ID,  id );

【讨论】:

【参考方案2】:

[已解决]

在阅读堆栈跟踪时,我注意到问题是引用了我用于验证规则的graphql-query-complexity。我删除了验证规则,现在一切正常!当然,我目前没有验证,但至少我可以从这里工作。感谢所有花时间回复的人!

【讨论】:

【参考方案3】:

我也遇到了类似的问题,并不确定发生了什么。 这里似乎报告了类似的问题 - https://github.com/apollographql/graphql-tools/issues/824

我们有 2 个选项来解决此问题。 - 第一个是一个简单的解决方法,当ID 只接受一个参数(不是对象)时,你不要强制它

const GET_USER_BY_ID= gql`
  query($id: ID) 
第二个选项是使用对象作为参数而不是原语。我继续这样做,即使我使对象和内部属性成为必需,它似乎对我来说也很好。 // 在客户端上

const GET_USER_BY_ID= gql`
   query($input: GetUserInput!) 
     getUser(input: $input) 
        id
        fullName
        role
     
`;  
        
const  data, error  = useQuery(GET_USER_BY_ID, 
  variables:  input:  id ,
);

//在服务端,定义输入类型

  input GetUserInput 
      id: ID!
    

【讨论】:

我尝试了这个解决方案,但不幸的是,我仍然收到错误消息,即我的变量没有被提供运行时值。

以上是关于Apollo 客户端没有读取使用 useQuery 钩子传入的变量的主要内容,如果未能解决你的问题,请参考以下文章

如何防止 Apollo 客户端 useQuery 中的错误传播?

Apollo 客户端 fetchMore 来自 useQuery 触发两个网络请求

如何使用 Apollo 客户端 useQuery 钩子防止不必要的重新获取?

Apollo 客户端 - 从缓存中读取

Apollo 客户端 useQuery 在 useMutation 后不更新数据

使用 apollo useQuery 时有没有办法禁用 apollo-link-dedup?