I've tried with repo as is and with data={props.data} as a prop.
What's going on?
Just got data to render.
Component Hierarchy BEFORE:
app: QueryRenderer >> index >> Router >> List: fragmentContainer >> Link: fragmentContainer
By removing the fragments and placing their content in app.js's query, I am able to pass their data down. However, when I used
// app.js
const query = graphql `query appQuery { ...List }`
// List.js
export default createFragmentContainer(List, graphql`
fragment List on RootQueryType {
allLinks {
...Link
}
}
`);
// Link.js
export default createFragmentContainer(Link, graphql`
fragment Link on Link {
id
description
url
}
`);
this returned an empty List object in the QueryRenderer, even though the query + fragments works perfectly on GraphiQL.
Interestingly, _app: QueryRenderer >> index >> Router >> List >> Link: fragmentContainer_ works with the adjustment of using link["__id"] instead of link.id in List.js when iterating over allLinks.
I.e.
// app.js
const query = graphql `query appQuery { allLinks { ...Link } }`
Oddly, I added back ...List and now the app is rendering.
This means that my issue was that I was passing the wrong props down the component hierarchy. The correct prop to pass down at each level is:
data={props}data={this.props.data}render={() => <List data={props.data}/>props.data.allLinks.map(link => <Link key={link["__id"]} data={link}/>const {description, url} = this.props.data;So I was passing data={props.data} in app.js, which at the top-level is undefined, instead of data={props}
As advice to anyone who runs into a similar issue:
console.log the props at each level of your component hierarchy to see if they suddenly disappear at one level; if so, adjust the prop you are passing at the level above
if you can't figure out what's going on (like me), do as above--remove the complexity that comes with using fragments by just putting the query at the top-level; then repeat (1) until your data renders; finally, introduce one fragment and get the data to render--keep doing this until you have the level of abstraction/collocation you want
This is a problem in your QueryRenderer logic
Also, to the maintainers of Relay, I would advise making this issue I ran into--passing down the right prop at the <QueryRenderer/> level (which is different from what you'll pass down at all levels after)--a bit more explicit in the documentation (i.e. "Thinking in Relay", "<QueryRenderer/>"--which does not provide a multi-level example, and "FragmentContainer" under "createFragmentContainer").
Just add a block quote that highlights the distinction made in this issue: https://github.com/facebook/relay/issues/1732
Because of the way the documentation comes off, I thought I just had to collocate the fragment with my component--not ALSO pass a prop down at every level of my component hierarchy if I use <QueryRenderer/>.
And I thought this because of content like:
With typical approaches to data-fetching we found that it was common for two components to have implicit dependencies. For example
<StoryHeader />might use some data without directly ensuring that the data was fetched. This data would often be fetched by some other part of the system, such as<Story />. Then when we changed<Story />and removed that data-fetching logic,<StoryHeader />would suddenly and inexplicably break.
Passing down a prop at every level of your component hierarchy is still a dependency.
@English3000 thanks for pointing this out! Happy to take PRs updating the docs
@jstejada As requested: https://github.com/facebook/relay/pull/2435
If this looks like a good start, I can also add some more explicit language to the 3 aforementioned pages (regarding the need to pass down props properly 馃槈)...
@jstejada Just wanted to touch in on how my content's been received.
Most helpful comment
Also, to the maintainers of Relay, I would advise making this issue I ran into--passing down the right prop at the
<QueryRenderer/>level (which is different from what you'll pass down at all levels after)--a bit more explicit in the documentation (i.e. "Thinking in Relay", "<QueryRenderer/>"--which does not provide a multi-level example, and "FragmentContainer" under "createFragmentContainer").Just add a block quote that highlights the distinction made in this issue: https://github.com/facebook/relay/issues/1732
Because of the way the documentation comes off, I thought I just had to collocate the fragment with my component--not ALSO pass a prop down at every level of my component hierarchy if I use
<QueryRenderer/>.And I thought this because of content like:
Passing down a prop at every level of your component hierarchy is still a dependency.