如何在 GraphQL 中正确链接 useQuery 和 useMutation?

Posted

技术标签:

【中文标题】如何在 GraphQL 中正确链接 useQuery 和 useMutation?【英文标题】:How do I chain useQuery and useMutation in GraphQL properly? 【发布时间】:2019-10-05 20:59:23 【问题描述】:

我有来自 react-apollo-hooks 的 useQuery 和 useMutation 背靠背。我希望能够将 useQuery 的返回值用作 useMutation 的变量。目前,useQuery 的值没有及时返回给变量,导致变量未定义。

const  data, error, loading  = useQuery(GET_POSTS,  
    variables: 
        id: props.match.params.id
    
)
const item = props.match.params.id
const owner = data.posts[0].author.id
const variables =  item , owner, startDate, endDate 
const bookItem = useMutation(CREATE_BOOKING_MUTATION, variables)

变量data.posts[0].author.id 显示未定义。如何确保返回的值是及时定义的?

【问题讨论】:

如果您可以从后端查询该数据,您是否已经拥有该数据可在解析器中用于突变? 【参考方案1】:

如何确保返回的值是及时定义的?

你可以简单地检查useQuery块之后的条件


更新

钩子不能有条件地调用。

通常的建议是将条件放在useEffect:

const  data, error, loading  = useQuery(GET_POSTS,  
  variables: 
    id: props.match.params.id
  
)
const item = props.match.params.id

// data.posts can be undefined at start
const owner = loading ? null : data.posts[0].author.id
const variables =  item , owner, startDate, endDate 
const bookItem = useMutation(CREATE_BOOKING_MUTATION, variables)
useEffect(() => 
  if(!loading) 
    bookItem(); // called when data ready
  
)

另一个选项:useApolloClient:

useQuery 加载突变所需的数据

const client = useApolloClient();

useEffect - 有条件地(!loadingdata 不为空)使用 client.mutate() 将获取的(查询中的)数据作为变量;

自定义钩子可以用 3 个参数完成:(query, mutation, mapDataToVariables )

【讨论】:

唯一的问题是如果我要在 if 语句之后放置 Hooks,我会收到错误消息,例如“有条件地调用 React Hook “useMutation”。必须在每个组件中以完全相同的顺序调用 React Hooks渲染”【参考方案2】:

我认为您可以在实际调用突变时传递变量,例如:

...
const bookItem = useMutation(CREATE_BOOKING_MUTATION)
...
if(!loading && !error && data) 
  bookItem(
    variables: 
      owner: data.posts[0].author.id,
      ...
    
  )

【讨论】:

以上是关于如何在 GraphQL 中正确链接 useQuery 和 useMutation?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 react-apollo graphql 查询中正确使用动态变量?

如何在 graphql 上正确创建 Id 字段以符合中继标准?

如何让 Vue (vue cli 3) 正确处理 GraphQL 文件?

graphql clientMutationId

如何正确使用 mat-autocomplete 和远程 graphQL 数据?

C#Text Parser就像GraphQL一样