React-apollo: 0.4.4: Mutations overlapping queries stop SSR

Created on 15 Aug 2016  路  3Comments  路  Source: apollographql/react-apollo

Take the following query:

const withGrades = graphql(gql`
  query grades($limit: Int!, $offset: Int, $order: Object, $search: Object) {
    grades (limit: $limit, offset: $offset, order: $order, search: $search) {
      count
      items {
        id
        title
        description
        createdAt
        updatedAt
      }
    }
  }
`, {
  options(ownProps) {
    const query = queryToState(ownProps.location.query);
    return {
      variables: {
        limit: query.limit || 10,
        offset: query.offset || 0,
        order: query.sortKey ? { [query.sortKey]: (query.sortDsc === true || query.sortDsc === 'true') } : null,
        search: query.search && Object.keys(query.search).length ? query.search : null
      }
    };
  },
  props({ ownProps, data }) {
    if (data.errors) return { errors: data.errors };
    return {
      loading: data.loading,
      refetchQuery: data.refetch,
      item: null,
      items: data.loading ? [] : data.grades.items,
      queryCount: data.loading ? 0 : data.grades.count,
    };
  }
});

Here SSR works well, but the mutation has no access to the refetchQuery prop on the client.

@graphql(gql`
  mutation ($title: String!, $description: String) {
    createGrade(title: $title, description: $description) { id }
  }
`,
{
  props({ ownProps, mutate }) {
    return {
      createItem(variables) {
        return mutate({ variables })
          .then(() => ownProps.refetchQuery());
      }
    }
  }
})
@withGrades // << BELOW
export class GradesSidebar extends React.Component {
  render() {
    return <Sidebar singular="Grade" {...this.props} />
  }
}

Here the exact opposite happens: SSR doesn't work, but the client can access the props normally.

@withGrades /// << ABOVE
@graphql(gql`
  mutation ($title: String!, $description: String) {
    createGrade(title: $title, description: $description) { id }
  }
`,
{
  props({ ownProps, mutate }) {
    return {
      createItem(variables) {
        return mutate({ variables })
          .then(() => ownProps.refetchQuery());
      }
    }
  }
})
export class GradesSidebar extends React.Component {
  render() {
    return <Sidebar singular="Grade" {...this.props} />
  }
}

I traced the issue to line 221 in graphql.jsx:

      // for use with getData during SSR
      static fetchData = operation.type === DocumentType.Query ? fetchData : false;

When I turned it into an if statement everything worked:

if (operation.type === DocumentType.Query)
    GraphQL.fetchData = fetchData;

And for the life of me I have no idea why. (I'd really appreciate an explanation!)

bug

All 3 comments

@voodooattack thank you for the excellent example and starting to hunt down the issue! I'll take a look and see what I can figure out!

@voodooattack I have no idea why that changes fixes it, but it definitely does! I've made the change and will release it and keep poking around to figure out why!

@jbaxleyiii Excellent. Thank you!

Was this page helpful?
0 / 5 - 0 ratings