React Apollo - Make Multiple Queries

心不动则不痛 提交于 2019-12-02 16:37:50

My preferred way is to use the compose functionality of the apollo client (docu).

EDIT: If you have more than one query you should name them.

So in your case, it could look like this:

import React, {Component} from 'react'
import queries from './queries'
import { graphql, compose } from 'react-apollo';

class Test extends Component {
...

  render() {
    ...
    
    console.log(this.props.subjectsQuery, this.props.appsQuery); // should show both 
    
    ...
  }
}

export default compose(
   graphql(queries.getSubjects, {
      name: "subjectsQuery"
   }),
   graphql(queries.getApps, {
      name: "appsQuery"
   }),
)(Test);

IMHO, one of the most neat solutions is described in the Apollo Client React implementation.
The basic idea is to wrap your queries into nested Query components. Using closure functions as component children makes it handy to delegate the results of one query down into another query and so on.

 const QueryOne = gql`
  query One {
    one
  }
`;

const QueryTwo = gql`
  query Two {
    two
  }
`;

const NumbersWithData = () => (
  <Query query={QueryOne}>
    {({ loading: loadingOne, data: { one } }) => (
      <Query query={QueryTwo}>
        {({ loading: loadingTwo, data: { two }}) => {
          if (loadingOne || loadingTwo) return <span>loading...</span>
          return <h3>{one} is less than {two}</h3>
        }}
      </Query>
    )}
  </Query>
);

If you don't want to reuse any of those queries independently, why not make a single request by combining both queries in one i.e:

const combinedQueries = gql`
{
  apps {
    id
    name
  }
  subjects {
    id
    name
  }
}
`

and then you can use it in your component

import React, {Component} from 'react'
import combinedQueries from './combinedQueries'

class Test extends Component {
   ...
   render() {
     ...
     if(!this.props.combinedQueries.loading) {
       console.log(this.props.combinedQueries.apps);
       console.log(this.props.combinedQueries.subjects);
     }
     ...
   }
}

export default graphql(combinedQueries, {name: 'combinedQueries'})(Test);

I'm using react-adopt to make this. It's really simple and keep our code clean.

Simple example:

import { adopt } from 'react-adopt';

...
render() {
  const Composed = adopt({
    first: ({ render }) => <Query query={FIRST_QUERY}>{ render }</Query>,
    second: ({ render }) => <Query query={SECOND_QUERY}>{ render }</Query>
  });

  return (
    <Composed>
      ({ first, second }) => {
        console.log('first', first)
        console.log('second', second)

        // validations (loading, error)

        return (
          <div>Your JSX</div>
        )
      }
    </Composed>
  )
}
...

There are a lot of examples using

const Composed = adopt({
  first: <Query query={FIRST_QUERY} />,
  second: <Query query={SECOND_QUERY} />
});

Be careful with <Query> component, It needs a children, otherwise, it will have the following error:

Warning: Failed prop type: The prop children is marked as required in Query, but its value is undefined.

To avoid the previous warning, I have found a possible solution:

first: ({ render }) => <Query query={FIRST_QUERY}>{ render }</Query>

Hope it helps you!

For Apollo 2.x: you can use react-adopt to compose the Queries and Mutations into a single level. (That lib will compose any components with render props, e.g. the React Context API.)

https://github.com/pedronauck/react-adopt

Another way around this is to use the props option.

export default compose(
  graphql(QUERY_2, {
    props: ({ data }) => ({ ...data }),
  }),
  graphql(QUERY_1, {
    props: ({ data }) => ({ ...data, myCustomAttribute: data.foo }),
  }),
)(Component);

I've found that this approach is a bit nicer for my use case.

Here is a link to the docs: https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-config-props

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!