relay: [Bug] - Relay fragment variables

We have encountered an strange behaviour of Relay. I will try to explain the best I can.

So we have an “main” relay container that fetches the data for corresponding store, and also includes and fragment from Ticket container. Ticket container render out custom table that has filter and sorting. So you can see that in StoreFrom component StoreTicketList container is import all required props are passed like Store fragment.

The problem occurs when you try to filter StoreList Ticket, I mean set filter or sort relay variables. You will get this error:

Warning: RelayContainer: component TicketList was rendered with variables that differ from the variables used to fetch fragment Store. The fragment was fetched with variables {"first":5,"after":null,"last":null,"before":null,"sort":null,"filter":null}, but rendered with variables {"first":5,"after":null,"last":null,"before":null,"sort":null,"filter":{"authorAccount":{"email":{"__e":"wrongEmail@email.com"}}}}. This can indicate one of two possibilities:

  • The parent set the correct variables in the query - TicketList.getFragment('Store', {...}) - but did not pass the same variables when rendering the component. Be sure to tell the component what variables to use by passing them as props: <TicketList ... first={...} after={...} last={...} before={...} sort={...} filter={...} />.
  • You are intentionally passing fake data to this component, in which case ignore this warning.

But those filter/sort variables are on StoreTicketList and they arent passed dow from parent to child container like in this case Store container to StoreListTicket container.

export class StoreForm extends React.Component {

  constructor(props) {
    super(props);

    const { Viewer: { store } } = props;

    this.state = {
      number: store && store.number !== null ? store.number : '',
    };
  }

  handleInsert = (model) => {
    console.log('Form mutation model : ', model);
  };

  render() {
    const { Viewer, relay: { variables: { update } } } = this.props;
    return (
      <div>
        <Form>
          <FormTitle title='Store Info' />
          <FormBody>
            <TextField
              required
              fullWidth
              name='number'
              value={this.state.number}
              floatingLabelText='Number'
            />
            <StoreTicketList Store={this.props.Viewer.store} />
          </FormBody>
        </Form>
      </div>
    );
  }
}
export default Relay.createContainer(StoreForm, {
  initialVariables: {
    id: null,
    update: false
  },
  prepareVariables({ id = null }) {
    return { id, update: (id !== null) };
  },
    fragments: {
        Viewer: (variables) => Relay.QL`
      fragment on Viewer {
        store(id: $id) @include(if: $update) {
          id,
          number
          ${StoreTIcketList.getFragment('Store')}
        }
      }
    `
    }
});

Ticket Container:

export const StoreTicketList = Relay.createContainer(TicketList, {
  initialVariables: {
    first: 5,
    after: null,
    last: null,
    before: null,
    sort: null,
    filter: null
  },
    fragments: {
        Store: () => Relay.QL`
      fragment on Store {
        ticketConnection(first: $first, after: $after, last: $last, before: $before, sort: $sort, filter: $filter) {
          count,
          pageInfo {
            hasNextPage,
            hasPreviousPage,
            startCursor,
            endCursor
          },
          edges{
            node{
              created,
              subject
            }
          }
        }
      }
    `
    }
});

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 25 (11 by maintainers)

Commits related to this issue

Most upvoted comments

@josephsavona Here is the Relay Playground link (sorry for just copy and pasting, I have tried to use many link shortners but it always says that it’s invalid 😄 )

https://facebook.github.io/relay/prototyping/playground.html#source= class TicketList extends React.Component { constructor(props) { super(props)%3B } filterHandler %3D () %3D> { const {relay} %3D this.props%3B relay.setVariables({ filter%3A { subject%3A !relay.variables.filter %3F { __e%3A ‘something’ } %3A { __ne%3A ‘else’ } } }) }%3B render() { return ( <div> <h1>Tickets<%2Fh1> <button onClick%3D{this.filterHandler}>Change filter<%2Fbutton> <div>{`Active filters%3A %24{JSON.stringify(this.props.relay.variables.filter%2C null%2C 2)}`}<%2Fdiv> <ul> {this.props.store.ticketConnection.edges.map(edge %3D> <li key%3D{edge.node.id}>{edge.node.title %2B ’ ’ %2B edge.node.subject} (ID%3A {edge.node.id})<%2Fli> )%7D%0A%20%20%20%20%20%20%20%20%3C%2Ful%3E%0A%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20StoreListTickets%20%3D%20Relay.createContainer(TicketList%2C%20%7B%0A%20%20initialVariables%3A%20%7B%0A%20%20%20%20first%3A%205%2C%0A%20%20%20%20after%3A%20null%2C%0A%20%20%20%20last%3A%20null%2C%0A%20%20%20%20before%3A%20null%2C%0A%20%20%20%20filter%3A%20null%0A%20%20%7D%2C%0A%20%20fragments%3A%20%7B%0A%20%20%20%20store%3A%20(variables)%20%3D%3E%20Relay.QL%60%0A%20%20%20%20%20%20fragment%20on%20Store%20%7B%0A%20%20%20%20%20%20%20%20ticketConnection(first%3A%20%24first%2C%20last%3A%20%24last%2C%20before%3A%20%24before%2C%20after%3A%20%24after%2C%20filter%3A%20%24filter%20)%20%7B%0A%20%20%20%20%20%20%20%20%20%20edges%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20node%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20id%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20title%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20subject%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%60%0A%20%20%7D%0A%7D)%3B%0A%0Aclass%20StoreForm%20extends%20React.Component%20%7B%0A%20%20%0A%20%20constructor(props)%20%7B%0A%20%20%20%20super(props)%3B%0A%20%20%20%20this.state%20%3D%20%7B%0A%20%20%20%20%20%20clickMe%3A%20false%0A%20%20%20%20%7D%0A%20%20%7D%0A%20%20%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3Cdiv%3E%0A%20%20%20%20%20%20%20%20%3Cbutton%20onClick%3D%7B()%20%3D%3E%20%7Bthis.setState(%7B%20clickMe%3A%20!this.state.clickMe%20%7D)%7D%7D%3E%0A%20%20%20%20%20%20%20%20%20%20First%20click%20%22change%20filter%22%20than%20ME%20%3A)%0A%20%20%20%20%20%20%20%20%3C%2Fbutton%3E%0A%20%20%20%20%20%20%20%20%3Ch1%3EStore%20-%20tickets%3C%2Fh1%3E%0A%20%20%20%20%20%20%20%20%3Cdiv%3E%7Bthis.props.viewer.store.name%7D%20(ID%3A%20%7Bthis.props.viewer.store.id%7D)%3C%2Fdiv%3E%0A%20%20%20%20%20%20%20%20%3CStoreListTickets%20store%3D%7Bthis.props.viewer.store%7D%20%2F%3E%0A%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20App%20%3D%20Relay.createContainer(StoreForm%2C%20%7B%0A%20%20initialVariables%3A%20%7B%0A%20%20%20%20id%3A%20%22c3RvcmU6MQ%3D%3D%22%0A%20%20%7D%2C%0A%20%20fragments%3A%20%7B%0A%20%20%20%20viewer%3A%20(variables)%20%3D%3E%20Relay.QL%60%0A%20%20%20%20%20%20fragment%20on%20Viewer%20%7B%0A%20%20%20%20%20%20%20%20store(id%3A%20%24id)%20%7B%0A%20%20%20%20%20%20%20%20%20%20id%2C%0A%20%20%20%20%20%20%20%20%20%20name%2C%0A%20%20%20%20%20%20%20%20%20%20%24%7BStoreListTickets.getFragment(‘store’)%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%60%0A%20%20%7D%0A%7D)%3B%0A%0Aclass%20AppHomeRoute%20extends%20Relay.Route%20%7B%0A%20%20static%20routeName%20%3D%20’AppHomeRoute’%3B%0A%20%20%0A%20%20static%20queries%20%3D%20%7B%0A%20%20%20%20viewer%3A%20()%20%3D%3E%20Relay.QL%60%0A%20%20%20%20%20%20query%20%7B%0A%20%20%20%20%20%20%20%20viewer%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%60%2C%0A%20%20%7D%3B%0A%7D%0A%0AReactDOM.render(%0A%20%20%3CRelay.RootContainer%0A%20%20%20%20Component%3D%7BApp%7D%0A%20%20%20%20route%3D%7Bnew%20AppHomeRoute()%7D%0A%20%20%2F%3E%2C%0A%20%20mountNode%0A)%3B%0A&schema=import%20%7B%0A%20%20GraphQLID%2C%0A%20%20GraphQLInt%2C%0A%20%20GraphQLObjectType%2C%0A%20%20GraphQLSchema%2C%0A%20%20GraphQLString%2C%0A%20%20GraphQLInputObjectType%0A%7D%20from%20’graphql’%3B%0A%0Aimport%20%7B%0A%20%20connectionArgs%2C%0A%20%20connectionDefinitions%2C%0A%20%20connectionFromArray%2C%0A%20%20fromGlobalId%2C%0A%20%20globalIdField%2C%0A%20%20nodeDefinitions%2C%0A%7D%20from%20’graphql-relay’%3B%0A%0A%2F%2F%20Model%20types%0Aclass%20Root%20%7B%7D%0Aclass%20Store%20%7B%7D%0Aclass%20Ticket%20%7B%7D%0A%0A%2F%2F%20Mock%20data%0Aconst%20viewer%20%3D%20new%20Root()%3B%0A%20%20%20%20%20%20viewer.id%20%3D%20’1’%3B%0A%20%20%20%20%20%20viewer.name%20%3D%20’Anonymous’%3B%0A%0Aconst%20stores%20%3D%20%5B%0A%20%20%7B%20name%3A%20’Store-1’%2C%20ticket%3A%20%5B1%2C2%2C3%5D%20%7D%2C%0A%20%20%7B%20name%3A%20’Store-2’%2C%20ticket%3A%20%5B2%2C4%2C3%5D%20%7D%2C%0A%20%20%7B%20name%3A%20’Store-3’%2C%20ticket%3A%20%5B2%2C%205%5D%20%7D%0A%5D.map((%7B%20name%2C%20ticket%20%7D%2C%20i)%20%3D%3E%20%7B%0A%20%20const%20a%20%3D%20new%20Store()%3B%0A%0A%20%20a.name%20%3D%20name%3B%0A%20%20a.ticket%20%3D%20ticket%3B%0A%20%20a.number%20%3D%20i%3B%0A%20%20a.id%20%3D%20%60%24%7Bi%7D%60%3B%0A%0A%20%20return%20a%3B%0A%7D)%3B%0A%0Aconst%20tickets%20%3D%20%5B%0A%20%20%7B%20title%3A%20’Test-1’%2C%20subject%3A%20’Subject-1’%20%7D%2C%0A%20%20%7B%20title%3A%20’Test-2’%2C%20subject%3A%20’Subject-2’%20%7D%2C%0A%20%20%7B%20title%3A%20’Test-3’%2C%20subject%3A%20’Subject-3’%20%7D%2C%0A%20%20%7B%20title%3A%20’Test-4’%2C%20subject%3A%20’Subject-4’%20%7D%2C%0A%20%20%7B%20title%3A%20’Test-5’%2C%20subject%3A%20’Subject-5’%20%7D%2C%0A%20%20%7B%20title%3A%20’Test-6’%2C%20subject%3A%20’Subject-6’%20%7D%0A%5D.map((%7B%20title%2C%20subject%20%7D%2C%20i)%20%3D%3E%20%7B%0A%20%20const%20a%20%3D%20new%20Ticket()%3B%0A%0A%20%20a.title%20%3D%20title%3B%0A%20%20a.subject%20%3D%20subject%3B%0A%20%20a.id%20%3D%20%60%24%7Bi%7D%60%3B%0A%0A%20%20return%20a%3B%0A%7D)%3B%0A%0Aconst%20exportObject%3D%20%7B%0A%20%20getRoot%3A%20(id)%20%3D%3E%20id%20%3D%3D%3D%20viewer.id%20%3F%20viewer%20%3A%20null%2C%0A%20%20getViewer%3A%20()%20%3D%3E%20viewer%2C%0A%20%20getStore%3A%20(id)%20%3D%3E%20stores.find(w%20%3D%3E%20w.id%20%3D%3D%3D%20id)%2C%0A%20%20getStores%3A%20()%20%3D%3E%20stores%2C%0A%20%20getConnectedTickets%3A%20(array)%20%3D%3E%20(array.map(id%20%3D%3E%20(tickets.find(w%20%3D%3E%20parseInt(w.id)%20%3D%3D%3D%20id))))%2C%0A%20%20getTicket%3A%20(id)%20%3D%3E%20tickets.find(w%20%3D%3E%20w.id%20%3D%3D%3D%20id)%2C%0A%20%20getTickets%3A%20()%20%3D%3E%20tickets%2C%0A%20%20Root%2C%0A%20%20Store%2C%0A%20%20Ticket%0A%7D%3B%0A%0Aconst%20%7BnodeInterface%2C%20nodeField%7D%20%3D%20nodeDefinitions(%0A%20%20(globalId)%20%3D%3E%20%7B%0A%20%20%20%20const%20%7Btype%2C%20id%7D%20%3D%20fromGlobalId(globalId)%3B%0A%20%20%20%20if%20(type%20%3D%3D%3D%20’Viewer’)%20%7B%0A%20%20%20%20%20%20return%20exportObject.getRoot(id)%3B%0A%20%20%20%20%7D%20else%20if%20(type%20%3D%3D%3D%20’store’)%20%7B%0A%20%20%20%20%20%20return%20exportObject.getStore(id)%3B%0A%20%20%20%20%7D%20else%20if%20(type%20%3D%3D%3D%20’ticket’)%20%7B%0A%20%20%20%20%20%20return%20exportObject.getTicket(id)%3B%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20return%20null%3B%0A%20%20%20%20%7D%0A%20%20%7D%2C%0A%20%20(obj)%20%3D%3E%20%7B%0A%20%20%20%20if%20(obj%20instanceof%20exportObject.Root)%20%7B%0A%20%20%20%20%20%20return%20viewerType%3B%0A%20%20%20%20%7D%20else%20if%20(obj%20instanceof%20exportObject.Store)%20%20%7B%0A%20%20%20%20%20%20return%20storeType%3B%0A%20%20%20%20%7D%20else%20if%20(obj%20instanceof%20exportObject.Ticket)%20%20%7B%0A%20%20%20%20%20%20return%20ticketType%3B%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20return%20null%3B%0A%20%20%20%20%7D%0A%20%20%7D%0A)%3B%0A%0Aconst%20ticketType%20%3D%20new%20GraphQLObjectType(%7B%0A%20%20name%3A%20’Ticket’%2C%0A%20%20fields%3A%20()%20%3D%3E%20(%7B%0A%20%20%20%20id%3A%20globalIdField(‘ticket’%2C%20(%7B%20id%20%7D)%20%3D%3E%20id)%2C%0A%20%20%20%20title%3A%20%7B%0A%20%20%20%20%20%20type%3A%20GraphQLString%2C%0A%20%20%20%20%20%20resolve%3A%20(%7B%20title%20%7D)%20%3D%3E%20title%0A%20%20%20%20%7D%2C%0A%20%20%20%20subject%3A%20%7B%0A%20%20%20%20%20%20type%3A%20GraphQLString%2C%0A%20%20%20%20%20%20resolve%3A%20(%7B%20subject%20%7D)%20%3D%3E%20subject%0A%20%20%20%20%7D%0A%20%20%7D)%2C%0A%20%20interfaces%3A%20()%20%3D%3E%20%5BnodeInterface%5D%0A%7D)%3B%0A%0Aconst%20%7B%20connectionType%3A%20ticketConnection%2C%20edgeType%20%3A%20graphQLTicketEdge%2C%20%7D%20%3D%20connectionDefinitions(%7B%20name%3A%20’Ticket’%2C%20nodeType%3A%20ticketType%20%7D)%3B%0A%0Aconst%20FilterObject%20%3D%20new%20GraphQLInputObjectType(%7B%0A%20%20name%3A%20’FilterObject’%2C%0A%20%20fields%3A%20%7B%0A%20%20%20%20__e%3A%20%7B%20type%3A%20GraphQLString%20%7D%2C%0A%20%20%20%20__ne%3A%20%7B%20type%3A%20GraphQLString%20%7D%0A%20%20%7D%0A%7D)%3B%0A%0Aconst%20storeType%20%3D%20new%20GraphQLObjectType(%7B%0A%20%20name%3A%20’Store’%2C%0A%20%20fields%3A%20()%20%3D%3E%20(%7B%0A%20%20%20%20id%3A%20globalIdField(‘store’%2C%20(%7B%20id%20%7D)%20%3D%3E%20id)%2C%0A%20%20%20%20number%3A%20%7B%0A%20%20%20%20%20%20type%3A%20GraphQLInt%2C%0A%20%20%20%20%20%20resolve%3A%20(%7B%20number%20%7D)%20%3D%3E%20number%0A%20%20%20%20%7D%2C%0A%20%20%20%20name%3A%20%7B%0A%20%20%20%20%20%20type%3A%20GraphQLString%2C%0A%20%20%20%20%20%20resolve%3A%20(%7B%20name%20%7D)%20%3D%3E%20name%0A%20%20%20%20%7D%2C%0A%20%20%20%20ticketConnection%3A%20%7B%0A%20%20%20%20%20%20type%3A%20ticketConnection%2C%0A%20%20%20%20%20%20args%3A%20%7B%0A%20%20%20%20%20%20%20%20filter%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20type%3A%20new%20GraphQLInputObjectType(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3A%20’Filter’%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20fields%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20title%3A%20%7B%20type%3A%20FilterObject%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20subject%3A%20%7B%20type%3A%20FilterObject%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20…connectionArgs%0A%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20resolve%3A%20(%7B%20ticket%20%7D%2Cargs)%20%3D%3E%20connectionFromArray(exportObject.getConnectedTickets(ticket)%2C%20args)%0A%20%20%20%20%7D%0A%20%20%7D)%2C%0A%20%20interfaces%3A%20()%20%3D%3E%20%5BnodeInterface%5D%0A%7D)%3B%0A%0Aconst%20%7B%20connectionType%3A%20storeConnection%2C%20edgeType%20%3A%20graphQLStoreEdge%2C%20%7D%20%3D%20connectionDefinitions(%7B%20name%3A%20’Store’%2C%20nodeType%3A%20storeType%20%7D)%3B%0A%0Aconst%20viewerType%20%3D%20new%20GraphQLObjectType(%7B%0A%20%20name%3A%20’Viewer’%2C%0A%20%20description%3A%20’Viewer’%2C%0A%20%20fields%3A%20()%20%3D%3E%20(%7B%0A%20%20%20%20id%3A%20globalIdField(‘Viewer’)%2C%0A%20%20%20%20store%3A%20%7B%0A%20%20%20%20%20%20type%3A%20storeType%2C%0A%20%20%20%20%20%20args%3A%20%7B%0A%20%20%20%20%20%20%20%20id%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20type%3A%20GraphQLID%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20resolve%3A%20(%2C%20%7B%20id%20%7D)%20%3D%3E%20exportObject.getStore(fromGlobalId(id).id)%0A%20%20%20%20%7D%2C%0A%20%20%20%20storeConnection%3A%20%7B%0A%20%20%20%20%20%20type%3A%20storeConnection%2C%0A%20%20%20%20%20%20args%3A%20connectionArgs%2C%0A%20%20%20%20%20%20resolve%3A%20(%2C%20args)%20%3D%3E%20connectionFromArray(exportObject.getStores()%2C%20args)%0A%20%20%20%20%7D%2C%0A%20%20%20%20ticket%3A%20%7B%0A%20%20%20%20%20%20type%3A%20ticketType%2C%0A%20%20%20%20%20%20args%3A%20%7B%0A%20%20%20%20%20%20%20%20id%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20type%3A%20GraphQLID%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20resolve%3A%20(%2C%20%7B%20id%20%7D)%20%3D%3E%20exportObject.getTicket(fromGlobalId(id).id)%0A%20%20%20%20%7D%2C%0A%20%20%20%20ticketConnection%3A%20%7B%0A%20%20%20%20%20%20type%3A%20ticketConnection%2C%0A%20%20%20%20%20%20args%3A%20connectionArgs%2C%0A%20%20%20%20%20%20resolve%3A%20(%2C%20args)%20%3D%3E%20connectionFromArray(exportObject.getTickets()%2C%20args)%0A%20%20%20%20%7D%0A%20%20%7D)%2C%0A%20%20interfaces%3A%20%5BnodeInterface%5D%0A%7D)%3B%0A%0Aconst%20queryType%20%3D%20new%20GraphQLObjectType(%7B%0A%20%20name%3A%20’Query’%2C%0A%20%20fields%3A%20()%20%3D%3E%20(%7B%0A%20%20%20%20node%3A%20nodeField%2C%0A%20%20%20%20viewer%3A%20%7B%0A%20%20%20%20%20%20type%3A%20viewerType%2C%0A%20%20%20%20%20%20resolve%3A%20()%20%3D%3E%20exportObject.getViewer()%0A%20%20%20%20%7D%0A%20%20%7D)%0A%7D)%3B%0A%0Aexport%20default%20new%20GraphQLSchema(%7B%0A%20%20query%3A%20queryType%0A%7D)%3B%0A

@mario-jerkovic This is super helpful, thank you for taking the time to create this. Having the playground instance makes it pretty clear what’s happening - the setState from the parent causes RelayContainer to recheck its props and it ends up comparing the variables in those props (empty, nothing is being passed) with what it fetched (the local setVariables changes) and reporting the discrepancy. This is just a warning so feel free to ignore for now, I’ll work on a fix (I’d normally suggest creating a PR but this is a notoriously tricky area in Relay).

Thank goodness I found this page. I have the same scenario as @jardakotesovec and get the same warnings. It took me days to suspect that I used Relay wrongly.

@mario-jerkovic I looked at the repo to try diagnose, but it would definitely be much easier for us to run and debug if you can repro in the Relay playground.

@josephsavona I will recreate my repo in playground if the repo by itself wasent helpful

Also getting this warning in scenario where I use only initialVariables and setVariables within one component to fetch data on demand and I don’t pass any variables via fragments.

Is @mario-jerkovic repro case enough to identify the issue or should I provide more details?

The problem appears to be in StoreForm - StoreForm is not passing variables to StoreTicketList as props. You should be able to fix this by either:

I would also highly recommend trying this on Relay master - we added some refinements to this warning and I’m not sure if they made the cut for the last release. I have a feeling that doing option 1 above plus upgrading to master will fix this warning.

I have tried to isolate the problem, and have created small example of the models on GraphQL side and Containers/Components on the frontend side.

Here is the repo link: https://github.com/mario-jerkovic/Relay-FragmentVariables

If you uncomment the code inside/js/routes/AppHomeRoute.js and/js/app.js, relay wont complaint about different variables, the only difference between working and not working code the the react-router-relay.