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

Posted

技术标签:

【中文标题】ApolloClient:重构 updateQueries 以使用 this.props.client.mutate【英文标题】:ApolloClient: Refactor updateQueries to work with this.props.client.mutate 【发布时间】:2017-09-01 14:41:33 【问题描述】:

注意:由于处理突变/查询/缓存更新的过程现在由 update 解决,我不再使用 uodateQueries,因此这个问题不再相关。

所以,我有一个从帖子到评论的一对多关系:

type Comments 
  createdAt: DateTime!
  id: ID!
  posts: Posts @relation(name: "PostsOnComments")
  text: String!
  updatedAt: DateTime!
  user: String!


type Posts 
  caption: String!
  comments: [Comments!]! @relation(name: "PostsOnComments")
  createdAt: DateTime!
  displaysrc: String!
  id: ID!
  likes: Int
  updatedAt: DateTime!

和一个 Root_Query,如 Apollo devTools(见附图)中所述,属于:

  query allPostsCommentsQuery 
    allPostses 
      id
      displaysrc
      caption
      likes
      comments 
        id
        posts 
          id
        
        text
        user
      
    
  

运行 Add_Comment_Mutation 或 Remove_Comment_MutationNew:

export const Add_Comment_Mutation = gql`
  mutation createComment ($id: ID, $textVal: String!, $userVal: String!) 
    createComments (postsId: $id, text: $textVal, user: $userVal)
      id
      text
      user
    
  
`;

export const Remove_Comment_MutationNew = gql`
  mutation removeComment ($cid: ID!) 
    deleteComments(id: $cid) 
      id
    
  
`;

没有正确更新响应式缓存,因此我的 UI 没有正确反映由 onClick 事件触发的 cmets 的任何添加/删除。

如何让 updateQueries 正确使用 this.props.client.mutate,因为当前尝试生成“错误:更新():$unshift 的预期目标是一个数组;未定义。”错误(见下文):

import  graphql, gql, withApollo  from 'react-apollo';
import ApolloClient from 'apollo-client';
import update from 'immutability-helper';
import  Add_Comment_Mutation, Remove_Comment_MutationNew  from '../graphql/mutations';

const Comments = React.createClass(

  removeCommentMutation(commentID) 
    console.log ("Remove_Comment_MutationNew is called for id=" + commentID);
    const  client  = this.props;

    return this.props.client.mutate(
      mutation: Remove_Comment_MutationNew,
      variables: 
        "cid": commentID,
      ,
      updateQueries: 
        allPostsCommentsQuery: (previous,  mutationResult ) => 
          console.log("Previous = " + previous);
          const newComment = mutationResult.data.removeComment;

          return update(previous, 
            allPostses: 
              comments: 
                $set: [newComment],
              ,
            ,
          );
        
      
    )
    .then(( data ) => 
      console.log('got data', data.deleteComments.id);
    )
    .catch(this.handleSubmitError);
  ,

产生的错误:

注意 - 问题似乎与

const newComment = mutationResult.data.removeComment;

作为“未定义”返回,而不是作为对象。

Error: update(): expected target of $unshift to be an array; got undefined.
    at invariant (http://localhost:7770/static/bundle.js:23315:16)
    at invariantPushAndUnshift (http://localhost:7770/static/bundle.js:71469:4)
    at Object.$unshift (http://localhost:7770/static/bundle.js:71430:6)
    at update (http://localhost:7770/static/bundle.js:71408:36)
    at update (http://localhost:7770/static/bundle.js:71410:32)
    at update (http://localhost:7770/static/bundle.js:71410:32)
    at allPostsCommentsQuery (http://localhost:7770/static/bundle.js:54181:52)
    at http://localhost:7770/static/bundle.js:39552:87
    at tryFunctionOrLogError (http://localhost:7770/static/bundle.js:39457:17)
    at http://localhost:7770/static/bundle.js:39552:44
    at Array.forEach (native)
    at data (http://localhost:7770/static/bundle.js:39536:47)
    at apolloReducer (http://localhost:7770/static/bundle.js:39789:24)
    at combination (http://localhost:7770/static/bundle.js:23011:30)
    at computeNextEntry (<anonymous>:2:27051)
    at recomputeStates (<anonymous>:2:27351)
    at <anonymous>:2:30904
    at Object.dispatch (http://localhost:7770/static/bundle.js:22434:23)
    at dispatch (<anonymous>:2:31397)
    at http://localhost:7770/static/bundle.js:41210:40
    at http://localhost:7770/static/bundle.js:73223:17
    at Object.dispatch (http://localhost:7770/static/bundle.js:23158:19)
    at http://localhost:7770/static/bundle.js:40597:30
tryFunctionOrLogError @ apollo.umd.js:1410
(anonymous) @ apollo.umd.js:1501
data @ apollo.umd.js:1485
apolloReducer @ apollo.umd.js:1738
combination @ combineReducers.js:132
computeNextEntry @ VM77918:2
recomputeStates @ VM77918:2
(anonymous) @ VM77918:2
dispatch @ createStore.js:179
dispatch @ VM77918:2
(anonymous) @ apollo.umd.js:3159
(anonymous) @ index.js:14
dispatch @ applyMiddleware.js:45
(anonymous) @ apollo.umd.js:2546

【问题讨论】:

【参考方案1】:

我不认为你可以连接突变。至少错误消息告诉我们。它应该是这样的:

...

removeCommentMutation(commentID) 
    const  client  = this.props;

    client.mutate(
      mutatation: Remove_Comment_Mutation,
      variables: 
        "cid": commentID
      ,
      updateQueries: 
        removeComment: (previous,  mutationResult ) => 
          const newComment = mutationResult.data.submitComment;

          return update(prev, 
            allPostses: 
              comments: 
                $unshift: [newComment],
              ,
            ,
          );
        
      
    );
  

  ...

【讨论】:

不幸的是,这只会引发Uncaught TypeError: Cannot read property 'kind' of undefined 错误。 更新了updateQueries 未使用正确命名查询的答案。应该是removeComment 不幸的是结果还是一样,尽管错误信息现在已经改变了。查看我更新的问题以查看我修改后的 client.mutate 代码和错误消息。 哦,对不起,我又错了。它当然必须是您要更改的查询,并且应该是 allPostsCommentsQuery 而不是 removeComment。你试过console.log previous allPostsCommentsQuery 没有解决问题,并且尝试 console.log previous 失败,因为该过程没有达到那么远。我认为是updateQueries 本身在整个过程中失败了。

以上是关于ApolloClient:重构 updateQueries 以使用 this.props.client.mutate的主要内容,如果未能解决你的问题,请参考以下文章

apolloClient.subsribe 未定义

ApolloClient 客户端的类型

ApolloClient:optimisticResponse 在更新期间变为“未定义”

ApolloLink 的 ApolloClient 类型错误

如何将 fetcher 传递给 ApolloClient()?

如何使用 ApolloClient 记录 HTTP 请求和响应