摘要:我的问题是,当我使用Relay
突变创建节点时,突变会在我的数据库中创建记录,但我的客户端本地数据不会更新,查询响应似乎缺少新节点。
讨论:我认为RANGE_ADD
应该将新节点ListingRating
添加到我的本地ListingRating
集合中,该集合应自动更新已连接的节点(Listing
和User
)。但是,根据relay
中的react-dev-tools
面板,该变异不包括我需要更新的任何字段。
问题:
这里RANGE_ADD
应该足够吗?如果是,那我的实施有什么问题?
我是否必须手动更新Listing
和User
个节点?如果是这样,怎么做?这些节点只能在变异payload
中深深嵌套,而FIELDS_CHANGE
在fieldId
的顶层需要payload
,对吧?
架构:我的架构包含Listing
个(广告),User
和Rating
s(用户对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',
},
}]
}
}
查询 :(不确定这是否相关)在我的应用中,我用来显示ListingRating
的查询是这样的:
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
}
}
答案 0 :(得分:0)
我放弃了上述方法,决定按照建议Relay.GraphQLMutation
API使用by the Relay docs to get ready for the Relay 2.0
API。
我无法说出我的OP中存在的问题,但从概念上讲,我的问题是我在我的UI中添加了一个节点,但未能显式获取父节点(即我添加了{{ 1}},但不更新ListingRating
,在我的应用中,Listing
是呈现ListingRating
的父级。
nodzk
的最新评论的github issue here& -one是票证。这是我的代码:
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()
。
此处的重要部分包括来自fragment
的{{1}}。这可确保更新商家信息中的集合,以包含新创建的Listing
。