score:3

Accepted answer

Let's take, for example, the following component:

ProfileWithData.js

import React, { Component, PropTypes } from 'react';
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';

class Profile extends Component { ... }
Profile.propTypes = {
  data: PropTypes.shape({
    loading: PropTypes.bool.isRequired,
    currentUser: PropTypes.object,
  }).isRequired,
};

// We use the gql tag to parse our query string into a query document
const CurrentUserForLayout = gql`
  query CurrentUserForLayout {
    currentUser {
      login
      avatar_url
    }
  }
`;

const ProfileWithData = graphql(CurrentUserForLayout)(Profile);

It would be quite easily wrapping it with a higher order component:

Profile.js

import React, { Component, PropTypes } from 'react';

export class Profile extends Component { ... }
Profile.propTypes = {
  data: PropTypes.shape({
    loading: PropTypes.bool.isRequired,
    currentUser: PropTypes.object,
  }).isRequired,
};

createProfileWithData.js

import React, { Component, PropTypes } from 'react';
import { graphql } from 'react-apollo';
import { Profile } from './Profile'

export default function createProfileWithData(query) => {
  return graphql(query)(Profile);
}

You would then use it like this:

Page.js

import React, { Component, PropTypes } from 'react';
import gql from 'graphql-tag';
import createProfileWithData from './createProfileWithData';

class Page extends Component {  

  renderProfileWithData() {

      const { textQuery } = this.props;
      // Simplest way, though you can call gql as a function too
      const graphQLQuery = gql`${textQuery}`;

      const profileWithDataType = createProfileWithData(graphQLQuery);

      return (
        <profileWithDataType />
      );
  }

  render() {

    return (<div>
                ..
                {this.renderProfileWithData()}
                ..
           </div>)
  }

}

Profile.propTypes = {
  textQuery: PropTypes.string.isRequired,
};

I think you get the point.

Of course, your Profile would not received props.data.currentUser, rather it would be props.data.* depending on the root queries, and you would handle it appropriately depending on the contents.

Note: this was written directly in Stack Overflow, so if you encounter any problems - lmk and I'll fix it.


Related Query

More Query from same tag