Great article, thanks Gabriel. Love these in-depth posts!
One thing I've never understood about relay is how to have a fragment request data that the fragment above it doesn't know about.
In your example, imagine the fragment that contains the tags. It would look something like
const blogPostTags = useFragment<BlogPostHeader_blogTags>(
graphql`
fragment BlogPostTags_blogPost on BlogPost {
tags {
slug
shortName
}
}
`,
blogPost
);
Now, imagine from this component we also wanted to be able to change add a new tag. So now we need not just the tags that the blog has, but all available tags.
If weren't using Fragments we could write a top level query that might look like
However, because we are using relay fragments the only way would be to pass down account from our top level query. But the BlogPost and BlogHeader don't require account. So we end up just passing account through two components that have no idea why they require account.
Now you can take this futher, maybe you have a <TagPicker /> component that can be re-used everywhere. It only requests tags { slug, shortName } but can be dozens of components down from the top level query where Blog {} is originally asked and where the fragment needs to be destructured.
Is there a nice way Relay can solve this?
Three solutions I've used is
1) Have the <TagPicker /> have query the graphql endpoint directly. But then I have unnecessary extra requests and repeated requests for the exact same data.
2) Have the <TagPicker /> use context to have the relay $key passed down without prop-drilling. However this causes race conditions when relay receives new data, and expects that the component will have it but because context hasn't re-rendered yet it's actually empty.
3) Prop-drilling down a dozen components, which makes refactoring very hard.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Great article, thanks Gabriel. Love these in-depth posts!
One thing I've never understood about relay is how to have a fragment request data that the fragment above it doesn't know about.
In your example, imagine the fragment that contains the tags. It would look something like
Now, imagine from this component we also wanted to be able to change add a new tag. So now we need not just the tags that the blog has, but all available tags.
If weren't using Fragments we could write a top level query that might look like
However, because we are using relay fragments the only way would be to pass down account from our top level query. But the
BlogPost
andBlogHeader
don't requireaccount
. So we end up just passingaccount
through two components that have no idea why they require account.Now you can take this futher, maybe you have a
<TagPicker />
component that can be re-used everywhere. It only requeststags { slug, shortName }
but can be dozens of components down from the top level query whereBlog {}
is originally asked and where the fragment needs to be destructured.Is there a nice way Relay can solve this?
Three solutions I've used is
1) Have the
<TagPicker />
have query the graphql endpoint directly. But then I have unnecessary extra requests and repeated requests for the exact same data.2) Have the
<TagPicker />
use context to have the relay$key
passed down without prop-drilling. However this causes race conditions when relay receives new data, and expects that the component will have it but because context hasn't re-rendered yet it's actually empty.3) Prop-drilling down a dozen components, which makes refactoring very hard.