I have 3 pages (components using react-router-relay
) in my app, ProductList
, ProductDetail
and BrandList
.
To illustrate the problem, let me walk through the flow and leave the code at the bottom.
First I go to
ProductList
and see the list of products, each with brand's name. It works as expected.Then I click on one of the product, this will render
ProductDetail
. Everything still works as expected.Now when I go to
BrandList
, the problem is Relay sends multiplenode(id: $id_0)
queries to server.
What happen is Relay's store has already fetched brands
after step 2 in ProductDetail
. And in step 3, BrandList
asks for more fields than Relay's store currently has. So Relay sends multiple node
queries, 30 queries as I have 30 brands, however this is inefficient and noticeably slow.
I can fix this by asking the same fields in both ProductDetail
([A]) and BrandList
([B]) (please see queries below). However, it means ProductDetail
gets unnecessary fields that it doesn't use.
I'm not sure if I've missed something very obvious here or there is a better way to avoid multiple node queries in this case. It would be arguably better if I could tell Relay to re-fetch brands
entirely in step 3 above when Relay has partial data already in store and going to send node
queries to get more fields.
// The relevant queries for each component. Please note the comments on [A] and [B] below
ProductList
export default Relay.createContainer(ProductList, {
fragments: {
viewer: () => Relay.QL`
fragment on Viewer {
id
products(first: 1000) {
edges {
node {
id
localId
name
brand {
name
}
}
}
}
}
`,
},
})
ProductDetail
export default Relay.createContainer(ProductDetail, {
fragments: {
product: () => Relay.QL`
fragment on Perfume {
id
localId
name
brand {
name
}
}
`,
viewer: () => Relay.QL`
fragment on Viewer {
id
brands(first: 1000) {
edges {
node {
localId
name // <------ [A] ask only name
}
}
}
}
`,
},
})
BrandList
export default Relay.createContainer(BrandList, {
fragments: {
viewer: () => Relay.QL`
fragment on Viewer {
id
brands(first: 1000) {
edges {
node {
id
localId
name
slug // <----- [B] ask more fields than [A]
country // <----- [B] ask more fields than [A]
}
}
}
}
`,
},
})