Giter Club home page Giter Club logo

Comments (12)

alloy avatar alloy commented on July 24, 2024 1

Ok, I see. So with Relay the idea is that the tree of fragments follows the tree of components. This makes it so you don’t need to know implementation details of any of the nested components, other than the ones you are directly composing in the module you’re working in.

In your example, the query in Container is composing a query with a fragment for which the QueryRenderer component isn’t rendering its component. Conversely, the FragmentOne component is composing a component for which its fragment isn’t fetching any data.

Rather than trying to pass data for another component (FragmentTwo) through your component (FragmentOne), you should make the passthrough component properly accept that data.

interface Props {
  foo: FragmentOne_foo;
  bar: FragmentOne_bar;
}

class FragmentOne extends React.Component<Props> {
  render() {
    return (
      <div>
        <FragmentTwo bar={this.props.bar} />
      </div>
    );
  }
}

export default createFragmentContainer(FragmentOne, {
  foo: graphql`
    fragment FragmentOne_foo on Foo @relay(plural: true) {
      id
      name
    }
  `,
  bar: graphql`
    fragment FragmentOne_bar on Bar @relay(plural: true) {
      ...FragmentTwo_bar
    }
  `
});

Now the root component only deals with details of the component it actually renders:

const query = graphql`
  query ContainerQuery {
    foo {
      ...FragmentOne_foo
    },
    bar {
      ...FragmentOne_bar
    }
  }
`;

class Container extends React.Component {
  render() {
    return (
      <QueryRenderer
        render={
          ({error, props}) => {
            if (props) {
              return <FragmentOne foo={props.foo} bar={props.bar} />;
            }
          }
        }
      />
    );
  }
}

Here’s the full patch for your example repo.


Slightly off-topic: I’m not sure how far along you are with designing your schema and I don’t want to be presumptuous as there have definitely been valid cases for this, but in my experience the need to pass on data from two root fields has often been a lack of modelling the data as a graph. (In our case we were initially basically passing all our REST endpoints through as root fields.) In practice, most screens usually are related to a single root field, from where all the other data fans out. E.g. in our case we’ll have a “artist page” and pretty much everything on that page will be related to that artist.

from relay-compiler-language-typescript.

kevinhughes27 avatar kevinhughes27 commented on July 24, 2024 1

Thanks for response! I might be missing another pattern in my app since the main reason for doing this was to avoid a query waterfall in this component. I'll do as you've suggested to fix my types for now. And you are correct this app is in the process of being remodelled as a graph and there are few awkward spots until the old code is fully deprecated :)

I'll close the issue.

from relay-compiler-language-typescript.

alloy avatar alloy commented on July 24, 2024

Thanks for the kind words!

At a glance it seems like it may be related to this change #61. I take it you are not using a single artefact directory, but rather the default colocated ones? And am I right in understanding that with v1.0.x of this plugin it didn’t break?

While this should definitely work and thus may need fixing, I’d suggest you use the single artefact directory feature anyways, because that will allow you to have type checking on your fragment references work.

from relay-compiler-language-typescript.

kevinhughes27 avatar kevinhughes27 commented on July 24, 2024

Yes I am using a single artefact directory.

from relay-compiler-language-typescript.

alloy avatar alloy commented on July 24, 2024

Oh, then those any types are really surprising to me. In that case, a repro would be very helpful.

from relay-compiler-language-typescript.

kastermester avatar kastermester commented on July 24, 2024

Without looking too much into this this part of your issue description looks strange to me:

FragmentContainerOne works fine and has the following Props:

interface Props {
  foo: FragmentContainerOne_foo;
  bar: FragmentContainerTwo_bar;
}

If this is the props for the FragmentContainerOne it should look like this:

interface Props {
  foo: FragmentContainerOne_foo;
  bar: FragmentContainerOne_bar;
}

With that said - the any types in the error message are confusing me quite a bit. If this is simply a misunderstanding then I'd also very much like to see a repro (link to some github repository exhibiting the error would do). Thanks! :)

from relay-compiler-language-typescript.

alloy avatar alloy commented on July 24, 2024

Good spot @kastermester 👍

I’m thinking that this component may be mixing fragments from other modules, in which case maybe it’s similar to #59 (comment) ?

from relay-compiler-language-typescript.

kevinhughes27 avatar kevinhughes27 commented on July 24, 2024

I'm trying to pass the props all the way down to the second fragment container. The first one only needs them in order to pass them down. Maybe this is wrong? It's my first relay app (also first typescript project). Thanks for the responses I'll make an example repo!

from relay-compiler-language-typescript.

kevinhughes27 avatar kevinhughes27 commented on July 24, 2024

Here you go!

https://github.com/kevinhughes27/nested_fragment_issue

src/FragmentOne.tsx:17:22 - error TS2322: Type 'ReadonlyArray<{ readonly id: string; readonly name: string; readonly " $refType": unique symbol; }>' is not assignable to type 'ReadonlyArray<_FragmentRefs<unique symbol>>'.
  Type '{ readonly id: string; readonly name: string; readonly " $refType": unique symbol; }' is not assignable to type '_FragmentRefs<unique symbol>'.
    Property '" $fragmentRefs"' is missing in type '{ readonly id: string; readonly name: string; readonly " $refType": unique symbol; }'.

17         <FragmentTwo bar={this.props.bar} />

from relay-compiler-language-typescript.

alloy avatar alloy commented on July 24, 2024

I might be missing another pattern in my app since the main reason for doing this was to avoid a query waterfall in this component.

I’m not sure if I fully understand this. My suggested change isn’t going to lead to more queries being performed, it’s still 1 query once merged by Relay.

from relay-compiler-language-typescript.

kevinhughes27 avatar kevinhughes27 commented on July 24, 2024

Oh sorry your suggestion won't. I meant the general need for 2 root query types. Does that make sense?

from relay-compiler-language-typescript.

alloy avatar alloy commented on July 24, 2024

Ah yep, gotcha 👍

from relay-compiler-language-typescript.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.