41

I have a queries file that looks like this:

import {gql} from 'react-apollo';

const queries = {
  getApps: gql`
    {
      apps {
        id
        name
      }
    }
  `,
  getSubjects: gql`
    {
      subjects {
        id
        name
      }
    }
  `
};

export default queries;

I then import this file to my React component:

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

class Test extends Component {
...
}

export default graphql(queries.getSubjects)(graphql(queries.getApps)(Test));

This will only get data for one of the queries (getApps) and not both. If I do one at a time so that it looks like this:

export default graphql(queries.getSubjects)(Test);

then it works but I don't have my other query. Yes, I have tested both separately and they work. How do I get it so that both queries show up in my props.data?

4

10 回答 10

45

我首选的方法是使用composeapollo 客户端 ( docu ) 的功能。

编辑:如果您有多个查询,您应该命名它们。

因此,在您的情况下,它可能如下所示:

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);

于 2017-04-13T05:41:45.260 回答
12

如果您不想独立重用这些查询中的任何一个,为什么不通过将两个查询组合在一起来发出单个请求,即:

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

然后你可以在你的组件中使用它

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);
于 2018-06-26T09:44:21.523 回答
11

恕我直言, Apollo Client React implementation中描述了最简洁的解决方案之一。
基本思想是将您的查询包装到嵌套的查询组件中。使用闭包函数作为子组件可以方便地将一个查询的结果委托给另一个查询,依此类推。

 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>
);
于 2018-07-16T10:13:13.480 回答
8

我正在使用react-adopt来做到这一点。这真的很简单,并保持我们的代码干净。

简单的例子:

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>
  )
}
...

有很多例子使用

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

小心<Query>组件,它需要一个孩子,否则会出现以下错误:

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

为了避免前面的警告,我找到了一个可能的解决方案:

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

希望对你有帮助!

于 2018-09-14T20:38:43.733 回答
5

对于Apollo 2.x:您可以使用react-adopt将 Queries 和 Mutations 组合成一个级别。(该库将使用渲染道具组合任何组件,例如 React Context API。)

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

于 2018-06-27T12:20:13.933 回答
4

Apollo Client 的出现使用Query Hooks;改变了一切。如果您在 2020 年或以后阅读本文;我很确定您可能正在使用 Apollo 客户端 useQuery 钩子。您可以根据需要多次调用 useQuery Hook 来执行这两个查询。您可以在其官方文档https://www.apollographql.com/docs/react/data/queries/中了解有关 useQuery 挂钩的更多信息,我发现它在我最近的项目中非常有用。例如

const queries = {
  getApps: gql`
    {
      apps {
        id
        name
      }
    }
  `,

  getSubjects: gql`
    {
      subjects {
        id
        name
      }
    }
  `
};

const { loading, error, data } = useQuery(queries);

const { loading:getSubjectsLoading, error:getSubjectsError, data:getSubjects } = useQuery(getSubjects);

if (loading || getSubjectsLoading) return "Loading...";
if (error || getSubjectsError ) return <p>Error :(</p>;


console.log(data);
console.log(getSubjects);
于 2020-07-03T00:31:02.950 回答
1

根据此链接,要使用compose()您需要按照以下步骤操作:

1-安装“重组”包使用npm i recompose

2-使用导入包import { compose } from "recompose";

3-以以下形式使用它:

export default compose(
  graphql(Query1, { alias: "Query1" }),
  graphql(Query2, { alias: "Query2" })
)(Test);

文档:https ://www.apollographql.com/docs/react/api/react-apollo/

于 2020-02-27T17:50:10.723 回答
0

由于 compose 已从 apollo 中删除,因此有一个名为 lodash 的替代库。{flowRight} 方法的作用与 compose 相同。只需按照以下步骤操作:-

  1. npm i -s lodash

  2. import {flowRight} from 'lodash'

  3. 将 compose 的用法与 flowRight 交换,所有其他代码都将工作相同。

于 2020-05-14T11:53:07.810 回答
0

解决此问题的另一种方法是使用该props选项。

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

我发现这种方法对我的用例来说更好一些。

这是文档的链接:https ://www.apollographql.com/docs/react/api/react-apollo.html#graphql-config-props

于 2018-05-02T20:10:40.287 回答
-1
  const { loading: cat_loading, cat_error, data: cat_data } = useQuery(categoriesAllQuery)
  const { loading: prod_loading, prod_error, data: prod_data } = useQuery(productsAllQuery)

  if (cat_loading || prod_loading) return <p>Loading ... </p>
  const { categoriesAll } = cat_data
  const { productsAll } = prod_data
于 2020-03-31T13:37:36.803 回答