反应阿波罗 - 进行多次查询

时间:2017-04-12 22:35:11

标签: javascript reactjs apollo react-apollo

我有一个如下所示的查询文件:

import {gql} from 'react-apollo';

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

export default queries;

然后我将此文件导入我的React组件:

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

class Test extends Component {
...
}

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

这只会获取其中一个查询(getApps)的数据,而不是两者。如果我一次做一个,看起来像这样:

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

然后它可以工作,但我没有其他查询。是的,我已经单独测试了它们并且它们有效。如何获取它以便在我的props.data中显示两个查询?

9 个答案:

答案 0 :(得分:35)

我首选的方法是使用apollo客户端的mvn gcloud:deploy -Dapp.id=test-project -Dapp.module=alpha -Dapp.version=x mvn gcloud:deploy -Dapp.id=test-project -Dapp.module=alpha -Dapp.version=y 功能(docu)。

编辑: 如果您有多个查询,则应为其命名。

所以在你的情况下,它看起来像这样:



compose




答案 1 :(得分:9)

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

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

答案 2 :(得分:5)

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

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

答案 3 :(得分:5)

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

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

答案 4 :(得分:2)

Apollo Client useQuery 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);

答案 5 :(得分:1)

根据此Link,要使用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/

答案 6 :(得分: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

答案 7 :(得分:0)

由于compose已从apollo中删除,因此存在另一个名为lodash的库。 {flowRight}方法的作用与compose相同。 只需执行以下步骤:-

  1. npm i -s lodash

  2. import {flowRight} from 'lodash'

  3. 用flowRight交换compose的用法,其他所有代码也一样。

答案 8 :(得分:-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