【问题标题】:How do I update connected Nodes in a RANGE_ADD mutation?如何更新 RANGE_ADD 突变中的连接节点?
【发布时间】:2017-06-13 08:24:55
【问题描述】:

总结:我的问题是,当我使用Relay 突变创建节点时,突变会在我的数据库中创建记录,但我的客户端本地数据没有更新,并且查询响应似乎缺少新节点。

讨论:我认为RANGE_ADD 应该将新节点ListingRating 添加到我的本地ListingRatings 集合中,这应该会自动更新连接的节点(ListingUser)。但是,根据react-dev-tools 中的relay 面板,突变不包括我需要更新的任何字段。

问题

RANGE_ADD 在这里应该足够吗?如果是这样,我的实现有什么问题?

我必须手动更新ListingUser 节点吗? 如果需要,怎么做?这些节点只能在突变payload 中深层嵌套使用,而FIELDS_CHANGE 需要fieldIdpayload 的顶层,对吗?

架构: 我的架构包含 Listings(广告)、Users 和 Ratings(用户对这些 Listings 的评分)。它看起来像这样:

type Listing = {
  ...
  ratings: [ListingRating]

}

type User = {
  ...
  ratings: [ListingRating]
}

type ListingRating = {
  rating: Int
  user: User
  listing: Listing
}

突变:我使用 scaphold.io 作为后端,因此无法控制突变结构(尽管它们符合 Relay 规范)。它们看起来像这样:

mutation createListingRating(input: CreateListingRatingInput!) { CreateListingRatingPayload }

// CreateListingRatingInput
{
  listingId: ID
  listing: CreateListingInput
  rating: Int
  userId: ID
  user: CreateUserInput
  clientMutationId: ID
}

// CreateRatingPayload
{
  changedListingRating: ListingRating
  changedEdge: ListingRatingEdge
  viewer: Viewer
  clientMutationId: String
}

中继突变

export default class CreateListingRating extends Relay.Mutation {

  getMutation() {
    return Relay.QL`
      mutation {
        createListingRating
      }
    `
  }

  getVariables() {
    return {
      userId: this.props.userId,
      listingId: this.props.listingId,
      rating: this.props.newRating,
    }
  }

  getFatQuery() {
    return Relay.QL`
      fragment on CreateListingRatingPayload @relay(pattern: true){
        changedEdge
        changedListingRating {
          listing
          user
          rating
        }
        viewer
      }
    `
  }

  getConfigs() {
    return [{
      type: 'RANGE_ADD',
      parentID: this.props.viewer.id,
      parentName: 'viewer',
      connectionName: 'allListingRatings',
      edgeName: 'changedEdge',
      rangeBehaviors: {
        '': 'append',
      },
    }]
  }

}

查询:(不确定这是否相关)在我的应用中,我用来显示ListingRatings 的查询如下所示:

query {
  getUserGroup(id: 'some-group-id') {
    users {
      edges {
        node {
          listings {
            edges {
              node {
                ratings {
                  edges {
                    node {
                      rating
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

突变请求:(即在 react-dev-tools 的中继面板中显示的内容)

mutation CreateListingRating($input_0:CreateListingRatingInput!) {

  createListingRating(input:$input_0) {

    ...F1
,

    clientMutationId
  }

}
fragment F0 on Viewer {

  id,

  user {

    firstName
,

    id
  }

}
fragment F1 on CreateListingRatingPayload {

  viewer {

    ...F0

  }

}

【问题讨论】:

    标签: reactjs graphql relayjs relay


    【解决方案1】:

    我放弃了上面的方法并决定使用Relay.GraphQLMutation API,正如建议的by the Relay docs to get ready for the Relay 2.0 API

    我不能说我的 OP 中存在什么问题,但从概念上讲,我的问题是我正在向我的 UI 添加一个节点,但未能显式获取父节点(即,我添加了一个 ListingRating,但不更新Listing,在我的应用程序中,它是呈现ListingRating 的父级。

    github issue herenodzk 的最新 cmets 之一是门票。这是我的代码:

    import ListingRelayContainer from 'components/Listing
    
    const Rating = (props, context) => {
      const _createListingRating = (input) => {
        createRating(input, context.relay)
      }
    // ...render etc
    }
    
    // this API requires a `Relay Environment`, so pull 
    // ours from context to avoid making anew
    Rating.contextTypes = {
      relay: Relay.PropTypes.Environment,
    }
    
    const createRating = (variables, relayStore) => {
      const query = Relay.QL`mutation {
        createListingRating(input:$input) {
          changedListingRating {
            rating
            id
            listing {
               ${ListingRelayContainer.getFragment('listing')}
            }
          }
        }
      }
      `
      const input = { input: variables }
      const mutation = new Relay.GraphQLMutation(
        query,
        input,
        null, // No files.
        relayStore,
        {
          onFailure: err => console.warn(err),
          onSuccess: () => console.log('Success!'),
        },
      )
      mutation.commit()
    }
    

    Bing-bang-boom,全部更新(虽然还没有乐观的更新)。

    请注意,我们甚至不必进入config(例如RANGE_ADD)。请注意,如果我们想对config 大惊小怪,我们会将一个对象传递给mutation.commit()

    这里的重要部分包括来自Listingfragment。这可确保列表上的评级集合被更新以包含新创建的Rating

    【讨论】:

    • 这里的乐观更新部分你弄清楚了吗?这就是我卡住的地方。我认为关于如何在网络上使用 GraphQLMutation 制作 RANGE_ADD 乐观查询的示例为零,所以很高兴知道你是否想通了!
    猜你喜欢
    • 2017-06-27
    • 2018-02-24
    • 2019-02-13
    • 2017-04-16
    • 2016-09-02
    • 1970-01-01
    • 2019-07-09
    • 2022-01-22
    • 1970-01-01
    相关资源
    最近更新 更多