Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Concepts: Dynamic gql, pass down as props #5

Closed
holyxiaoxin opened this issue Oct 3, 2017 · 2 comments
Closed

Concepts: Dynamic gql, pass down as props #5

holyxiaoxin opened this issue Oct 3, 2017 · 2 comments

Comments

@holyxiaoxin
Copy link

I want to discuss some concepts about ability to use/switch to multiple gql query while connecting it to the same component. What I meant was something like this:
http://dev.apollodata.com/react/api-graphql.html#graphql-config-skip

export default compose(
  graphql(gql`query MyQuery1 { ... }`, { skip: props => !props.useQuery1 }),
  graphql(gql`query MyQuery2 { ... }`, { skip: props => props.useQuery1 }),
)(MyComponent);
function MyComponent({ data }) {
  // The data may be from `MyQuery1` or `MyQuery2` depending on the value
  // of the prop `useQuery1`.
  console.log(data);
}

However, this still seems very static, and "declarative". Consider you have 2 very similar Scroll components, that has exactly the same type of View. One lists the top 100 movies, the other lists all movies matching a given set of movie Director names. The only difference here would be the gql queries, and query variables for them. It'd be nice to pass the gql query down as props.

Consider these 2 views: IndexView, MoviesView.

The way i consume the dynamic gql query and connect it to the component is to create a wrapper component like this. (In comments)

const MoviesWithCusorWrapper = (props) => {
  const { gql = moviesQuery } = props;
  const Comp = compose(graphql(gql, gqlConfig), withLoading)(Movies);

  return React.createElement(Comp, props);
};

or to simplify it further (without the added recompose and gqlConfig options, only the idea of the Wrapper Component):

const MoviesWrapper = (props) => {
  const Comp = graphql(props.gql)(Movies);

  return React.createElement(Comp, props);
};

I've abstracted the wrapper component as a HOC to something like this:

import React from 'react';
import _ from 'lodash';
import { compose } from 'recompose';
import { graphql } from 'react-apollo';

const withGqlPropsHOC = (gqlDefault, { enhancers, gqlConfig }) => Comp => (props) => {
  const { gql = gqlDefault } = props;
  // preppedEnhancers takes care of undefined, single parameter, array of enhancers
  const preppedEnhancers = _.compact(Array.isArray(enhancers) ? enhancers : [enhancers]);
  const EnhancedComp = compose(graphql(gql, gqlConfig), ...preppedEnhancers)(Comp);

  return React.createElement(EnhancedComp, props);
};

export default withGqlPropsHOC;

so we can use it like this:

export default
withGqlProps(moviesQuery, { enhancers: [withLoading], gqlConfig })(Movies);

Which results in 2 different query by passing it down as props,
image
image

Is there already something similar provided by apollo-core/apollo libraries? Any thoughts?

@MacKentoch
Copy link
Owner

MacKentoch commented Oct 10, 2017

Hi,

Huge issue 😄

I don't know your use-case but depending on it, what about having 2 components

  • a component for the case MyQuery1
  • and another for MyQuery2?

I mean connect sub components to each query.

@MacKentoch
Copy link
Owner

This is not an issue (so I close), but feel free to use it to keep talking about it if you want.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants