Hacker News new | ask | show | jobs
by exogen 3159 days ago
I've considered that, but it's extremely annoying (and still not really possible with Relay or Apollo). Not only would I be relying on Apollo's query batching/merging in order to not make 100 different queries over the network, but each child component would need to duplicate the base query and variables, meaning they'd need the props that correspond to query variables passed all the way down the component tree to them.

Consider the Artist.Name and Artist.Disambiguation components in my GitHub example. Notice how they don't need the `mbid` prop that the ancestor component provides. I want a component like that for every single field in my Artist schema. If every one of those components duplicated the artist query, they'd all need to be passed the `mbid`, because that's how it determines what artist to retrieve. It's possible to do some tricks with `context` like I'm doing now, but I don't really trust that it's a better solution than having one query execution point with an extendable query.

3 comments

You can have child components that get some data from props and some from their own query. Just inject the props into the relay renderer.
Yes, I'm saying that getting those props to those children in the first place is annoying to do and I'd still have to build a bunch of `context` helpers on top of Relay and Apollo to make doing that nice.

This is the API I want:

    <Artist mbid="abc-123">
      <Artist.Name />
      <Artist.Disambiguation />
      <SomeOtherComponentThatHasArtistFieldDescendants />
    </Artist>
This is the API you're saying I would have to use with vanilla Relay and Apollo:

    <Artist mbid="abc-123">
      <Artist.Name mbid="abc-123" />
      <Artist.Disambiguation mbid="abc-123" />
      <SomeOtherComponentThatHasArtistFieldDescendants mbid="abc-123" />
    </Artist>
Assuming I did build HOCs for doing so, the difference boils down to this: in your approach, query variable props would magically be passed down the component tree via `context` and used by descendant components in duplicated queries. The way I've built it, query fragments are magically passed up the component tree via `context` and used in a single query.

Considering neither are possible with vanilla Relay and Apollo and I need to build these helper HOCs either way, I don't really see why what you're proposing is better. I had already considered them both and deliberately did not do it that way.

> I've considered that, but it's extremely annoying (and still not really possible with Relay or Apollo)

It’s easy with Relay. With Classic you render a RelayRenderer. In Relay Modern you render a QueryRenderer. Either way, you can issue more queries than just your root query and it’s as easy as rendering a React component.

It’s not. I’ve tried with Relay Modern. See the API I want elsewhere in the thread.
Yes I think I see what you mean now.
Consider using conditional fields using the @include or @skip directives
I addressed that in the original post. That requires (1) adding potentially hundreds of boolean query variables to the query (and neither Apollo nor Relay give you any affordance for populating these from context, which you'd need for descendant components to add them) and (2) the parent query still knowing and listing out every possible field that could be added to the query, but with a @skip directive on it and (3) how do you deal with fields on nested objects? Not feasible in the slightest.