Giter Site home page Giter Site logo

Q: Polymorphic composition about relay HOT 8 CLOSED

facebook avatar facebook commented on May 8, 2024
Q: Polymorphic composition

from relay.

Comments (8)

vladar avatar vladar commented on May 8, 2024 2

@josephsavona unfortunately it doesn't help in following situations:

  1. Trully dynamic components when parent is not aware of all possible children (like Relay.RootContainer)
  2. Code splitting - when actual child component is loaded on demand and you don't have reference to it's container at static time

Would be great if Relay could provide some solution for these cases as well as they are fairly common.

from relay.

josephsavona avatar josephsavona commented on May 8, 2024

Great question. Relay has support for this, but it's an advanced feature and so we didn't initially document it. Note that the API is likely to change (but we'll mark it as deprecated before doing so). However, we'd appreciate your feedback on this API and any suggestions you may have.

Current API

Here's how you can construct a container whose child is dynamic based on the current route:

Relay.createContainer(App, {
  fragments: {
    foo: () => Relay.QL`
      fragment on Node {
        ${Header.getFragment('foo')}
        ${route => switch (route.name) {
          case 'RouteA': return ContainerA.getFragment('foo');
          case 'RouteB': return ContainerB.getFragment('foo');
          default: return null;
        }}
      }
    `,
  },
});

In addition to the standard forms of fragment composition documented here, you can also pass a value of the type

(route: {name: string} => ?Fragment;

Basically, a function that accepts an object with a name: string property, and returns an (optional) fragment.

(Proposed) Future API

The future API we've explored for this would use GraphQL directives:

...
foo: () => Relay.QL`
   ${Header.getFragment(...)},
   ${ContainerA.getFragment(...)} @relay(route: 'RouteA'),
   ${ContainerB.getFragment(...)} @relay(route: 'RouteB'),
`

from relay.

devknoll avatar devknoll commented on May 8, 2024

This is great, thank you! I'll try it out and get back to you.

from relay.

devknoll avatar devknoll commented on May 8, 2024

Wait... @josephsavona

foo: () => Relay.QL`
      fragment on Node {
        ${Header.getFragment('foo')}
        ${route => switch (route.name) {
          case 'RouteA': return ContainerA.getFragment('foo');
          case 'RouteB': return ContainerB.getFragment('foo');
          default: return null;
        }}
      }
    `,

Wouldn't this only let the composed fragments compose on Node? If ContainerB wanted a User instead, he wouldn't be able to fragment on that, right?

from relay.

josephsavona avatar josephsavona commented on May 8, 2024

@devknoll With the Relay GraphQL spec most types will implement the Node interface, so this would be okay. In your example if RouteA matched, you'd end up with the following (valid) GraphQL:

fragment App on Node {
   ...Header
   ...ContainerB
}
fragment Header on ...
fragment ContainerA on User {...}

from relay.

devknoll avatar devknoll commented on May 8, 2024

Yup! Just realized that. It looks like there may actually be a bug with graphql-ruby or at least my implementation. Thanks again, and sorry for bothering 😄

from relay.

devknoll avatar devknoll commented on May 8, 2024

For posterity, the actual query being generated actually looks more like this:

query Dashboard { 
  viewer {
    id,
    ...Header
  }
}

fragment ContainerA on Viewer {
  name,
  id
}

fragment Header on Node
{
  id,
  ...ContainerA
}

This looks like it should be syntactically the same as the above, but I think the first fragment on Node caused graphql-ruby to lose the Viewer type information, forcing it to fall back to a default-implemented resolve_type.

from relay.

nodkz avatar nodkz commented on May 8, 2024

Referenced to #896
and http://stackoverflow.com/questions/35067685/getfragment-from-a-dynamic-component-in-relay

from relay.

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.