GraphQL 突变后的 updateQueries 无法与 Apollo 客户端一起使用

Posted

技术标签:

【中文标题】GraphQL 突变后的 updateQueries 无法与 Apollo 客户端一起使用【英文标题】:updateQueries after GraphQL mutation not working with the Apollo client 【发布时间】:2017-07-26 08:00:49 【问题描述】:

在我的应用中发送createMessage 突变后,我想使用updateQueries 更新本地ApolloStore

我的设置如下:

const ChatWithAllMessages = graphql(allMessages, name: 'allMessagesQuery')(Chat)
export default graphql(createMessage, 
   props(ownProps, mutate) 
    return 
      createMessageMutation(text, conversationId) 
        return mutate(
          variables:  text, conversationId ,
          updateQueries: 
            allConversations: (previousState, mutationResult) => 
              console.log('Chat - did send mutation for allConversationsQuery: ', previousState, mutationResult)
              return ...
            
          
        )
      
    
  
)(ChatWithAllMessages)

我在我的代码中调用createMessageMutation,如下所示:

_onSend = () => 
  this.props.createMessageMutation(this.state.message, this.props.conversationId)

通过这种设置,我希望我在 updateQueries 的值中指定的函数能够被执行,但是,这似乎没有发生(日志语句永远不会被打印)。

作为参考,ApolloStore 中的 allConversation 查询如下所示:

另外,这在我的 JS 代码中是这样定义的:

const findConversations = gql`
    query allConversations($customerId: ID!) 
        allConversations(filter: 
          customer: 
            id: $customerId
          
        )
            id
            updatedAt
            slackChannelName
            agent 
                id
                slackUserName
            
            messages(last: 1) 
                id
                text
                createdAt
            
        
    
`

有人发现我做错了吗?

【问题讨论】:

【参考方案1】:

如果您在同一组件中使用查询和突变,您可以组合突变和查询。就像在解决方案 1 中一样。

如果您不需要组件中的突变,您可以添加命名查询(由于版本 0.11.1 / 特此相关查询必须至少调用一次,否则阿波罗存储不知道该查询)或者您可以将查询本身添加到 updateQueries。

1) 使用突变和查询的组件

import  compose  from 'react-apollo';

...

import findConversationsQuery from './.../findConversationsQuery';

...

const ChatWithAllMessages = compose(
    graphql(allMessages, name: 'allMessagesQuery'),
    findConversationsQuery,
    graphql(createMessage, 
      props( ownProps, mutate ) 
        return 
          createMessageMutation(text, conversationId) 
            return mutate(
              variables: 
                text,
                conversationId
              ,
              updateQueries: 
                allConversations: (previousState, 
                  mutationResult
                ) => 
                  console.log('Chat - did send mutation for allConversationsQuery: ', previousState, mutationResult)
                  return ...
                
              
            )
          
        
      
    )(Chat)

使用文件中定义的 graphql 查询,因为您只想将其实例化一次

import  graphql  from 'react-apollo';
import gql from 'graphql-tag';

const findConversations = gql`
    query allConversations($customerId: ID!) 
        allConversations(filter: 
          customer: 
            id: $customerId
          
        )
            id
            updatedAt
            slackChannelName
            agent 
                id
                slackUserName
            
            messages(last: 1) 
                id
                text
                createdAt
            
        
    
`

const findConversationsQuery = graphql(findConversations, 
   name: "findConversationsQuery"
);

export default findConversationsQuery

【讨论】:

> updateQuery 功能仅在突变的视图包含对查询的引用时才被调用。你有那个声明的参考吗? apollo的文档中没有直接这样写。当您阅读updateQueries definition 时,有两条语句“我们通过 CommentsPage 组件可以调用的函数 prop 公开此突变”和“cmets 页面本身使用以下查询呈现”。所以我认为查询必须在组件的道具中。 提到this comment 听起来这种行为是一个错误。尽管我不清楚这里的当前协议。 是的,你是对的,所以也许在 0.11.1 版本中它可以在不编写查询和突变的情况下工作 突变不需要持有对查询的引用,它只需要知道查询的名称(不是JS变量名称,而是graphql查询字符串中给出的名称,即 在“查询 (var1: String, ...) ... ") 中。 UpdateQueries 仅在之前执行了命名查询时才有效,因为否则 Apollo 客户端不知道该查询。为了规避这个问题,您可以直接向 updateQueries 提供查询 + 变量(而不是查询名称)。你能相应地更新你的答案吗?

以上是关于GraphQL 突变后的 updateQueries 无法与 Apollo 客户端一起使用的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL - 突变响应后的自定义错误消息

Apollo 中的自动 UI 更新问题:`updateQuery` 不能与 `subscribeToMore` 一起正常工作

Sequelize with GraphQl:如何使用突变更新字段

Vuex 状态随突变而变化 - apollo graphql 查询

ApolloClient:重构 updateQueries 以使用 this.props.client.mutate

从另一个突变中调用 GraphQL 突变?