普通数组上的中继突变不起作用

Posted

技术标签:

【中文标题】普通数组上的中继突变不起作用【英文标题】:Relay mutation on plain array is not working 【发布时间】:2016-08-04 02:14:46 【问题描述】:

我很难弄清楚如何通过中继对普通数组进行突变。

我正在尝试为帖子添加新标签。 服务端添加成功后,客户端不会更新。

我必须手动重新加载才能看到新标签。 REQUIRED_CHILDRENthis.props.relay.forceFetch() 我都试过了,但都无济于事。

另外,尝试FIELDS_CHANGE 发帖。

GraphQL 架构:

Post 
  id: ID!
  text: String!
  tags: [Tag!]!


Tag 
  id: ID!
  name: String!

AddTagToPostMutation:

  static fragments = 
    post: () => Relay.QL`
      fragment on Post 
        id
        tags
      
    `,
  

  getMutation() 
    return Relay.QL`mutation  addTagToPost `;
  

  getVariables() 
    return 
      name: this.props.tag.name,
    ;
  

  getFatQuery() 
    return Relay.QL`
      fragment on AddTagToPostMutationPayload 
        tag 
          id
          name
        
        post 
          id
          tags
        
      
    `;
  

  getConfigs() 
    return [
      type: 'REQUIRED_CHILDREN',
      children: [Relay.QL`
        fragment on AddTagToPostMutationPayload 
          tag 
            id
            name
          
          post 
            id
            tags
          
        
      `],
    ];
  

  getOptimisticResponse() 
    return 
      tag: 
        name: this.props.tag.name,
      ,
      post: 
        id: this.props.post.id,
      ,
    ;
  

【问题讨论】:

【参考方案1】:

我认为你应该只在这种情况下使用 FIELDS_CHANGE。

  getConfigs() 
    return [
      type: 'FIELDS_CHANGE',
      fieldIDs: post: this.props.post.id,
    ];
  

  getOptimisticResponse() 
    return 
      post: 
        id: this.props.post.id,
        tags: [...this.props.post.tags, this.props.tag],
      ,
    ;
  

【讨论】:

我也尝试过 FIELDS_CHANGE,但也没有用。 @Joon 你能检查一下哪个服务器从突变请求中实际返回到 Relay(例如,你可以使用 React 开发工具或只是 chrome 网络选项卡)?您是否一开始看到乐观的反应“眨眼”,好像先添加标签然后删除?【参考方案2】:

正如 freiksenet 已经指出的那样,FIELDS_CHANGE 应该在 getConfigs() 函数中使用。我采用了您的架构,实现了 GraphQL 类型、服务器端和客户端突变以向帖子添加标签。客户端成功更新。我将在我的回答中详细说明解决方案。

首先,检查您的服务器端突变。我的实现使用graphql 和graphql-relay 库,如下所示。请注意,服务器端突变的输出是已添加标签的帖子。这篇文章的 ID 是作为输入提供的。

const AddTagToPostMutation = mutationWithClientMutationId(
  name: 'AddTagToPost',
  inputFields: 
    postId:  type: new GraphQLNonNull(GraphQLID) ,
    name:  type: new GraphQLNonNull(GraphQLString) ,
  ,
  outputFields: 
    post: 
      type: PostType,
      resolve: (id) => getPost(id),
    ,
  ,
  mutateAndGetPayload: (postId, name) => 
    const id = fromGlobalId(postId).id;
    addTagToPost(id, name);
    return id;
  ,
);

使用graphiql,您可以测试您的突变:

mutation 
  addTagToPost(input:
      postId: "UG9zdDpwb3N0Mg==" 
      name:"a new tag name" 
      clientMutationId:"123244") 
    post 
      id
      text
      tags 
        id
        name
      
    
  

我为根查询的所有帖子添加了一个字段posts。使用graphiql,我首先检查了帖子ID并使用了上面的一个。

使用react-relay,客户端变异代码如下所示。它传递了一个 prop post,其 ID 用作 getVariables() 函数中的输入变量。在getConfigs() 函数中,我们指定必须更新post 字段。载荷字段 post 和传递的 prop post 之间的关联是使用 FIELDS_CHANGE 突变类型建立的。

export default class AddTagToPostMutation extends Relay.Mutation 
  getMutation() 
    return Relay.QL`mutationaddTagToPost`;
  

  getVariables() 
    return 
      postId: this.props.post.id,
      name: this.props.name,
    ;
  

  getFatQuery() 
    return Relay.QL`
      fragment on AddTagToPostPayload 
        post 
          id,
          tags 
            id,
            name,
          
        
      
    `;
  

  getConfigs() 
    return [
      type: 'FIELDS_CHANGE',
      fieldIDs: 
        post: this.props.post.id,
      ,
    ];
  

  static fragments = 
    post: () => Relay.QL`
      fragment on Post 
        id,
      
    `,
  ;

客户端突变是这样调用的:

Relay.Store.commitUpdate(new AddTagToPostMutation(
      post: postToModify,
      name: tagName,
    ));

【讨论】:

以上是关于普通数组上的中继突变不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Appsync 更新和删除突变不起作用

Vuex 突变和操作不起作用

使用 ApolloClient 将变量传递给 GraphQL 突变似乎不起作用

中继片段传播不起作用

嵌套突变似乎在 Lighthouse 3.7 中不起作用

APOLLO CLIENT - 突变不起作用(无法读取未定义的属性“数据”)