Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional fragments or embedded root-containers when using Relay with React-Native

I've got relay working with react-native, but I'm confused about how to best utilize relay routes and root containers, especially when working with a Navigator that renders multiple routes.

Take the following class:

var Nav = React.createClass({

 renderScene(route, nav) {
   switch(route.id) {
     case 'first':
       return <First navigator={nav} />
     case 'second':
       return <Second navigator={nav} />
   }
 },

 render() {
   <Navigator
     initialRoute={{ id: 'first' }}
     renderScene={this.renderScene}
   />
 }

})


module.exports = Relay.createContainer(Nav, {   
  fragments: {
    viewer: () => Relay.QL`
      fragment on User {
        ${First.getFragment('viewer'},
        ${Second.getFragment('viewer'}
      }
    `   
  } 
})

In my parent route, I then request the User fragment which builds the query.

The problem is that the fragment will be including those fields defined by both the first and second components, even if only one of them is being displayed at a time.

In this case should I:

1) return another Relay.RootContainer in the renderScene callback? Is it generally a bad idea to embed Relay.RootContainers within each-other?

renderScene(route, nav) {
  switch(route.id) {
    case 'first':
      return (
        <Relay.RootContainer
           Component={First}
           route={new FirstRoute()}
           renderFetched={(data) => {
             return <First navigator={nav} {...data} />
           }}
        />
      )
  }
}

2) Use conditional variables to include a fragment?

initialVariables: {
  first: true
},

fragments: {
  viewer: (variables) => Relay.QL`
    fragment on User {
      ${First.getFragment('viewer').if(variables.first)
    }
  `
}

Or are there other suggestions?

like image 683
bento Avatar asked Sep 15 '15 04:09

bento


1 Answers

Using something like this:1

function matchRoute(route, map) {
  return map[route.name] ? map[route.name]() : null;
}

Try this:

fragments: {
  viewer: (variables) => Relay.QL`
    fragment on User {
      ${route => matchRoute(route, {
        FirstRoute: () => First.getFragment('viewer'),
        SecondRoute: () => Second.getFragment('viewer'),
      }},
    }
  `,
}

[1]: medium.com/@cpojer/relay-and-routing

like image 188
steveluscher Avatar answered Oct 27 '22 16:10

steveluscher