web-dev-qa-db-ja.com

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)のデータのみを取得します。次のように一度に1つずつ実行すると、

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

それは動作しますが、他のクエリはありません。はい、両方を別々にテストしましたが、動作します。 props.dataに両方のクエリが表示されるようにするにはどうすればよいですか?

31
user2465134

私の好ましい方法は、apolloクライアントのcompose機能を使用することです( doc )。

編集:複数のクエリがある場合は、名前を付ける必要があります。

したがって、あなたの場合、次のようになります。

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

私見、最もきちんとしたソリューションの1つは ApolloクライアントReact実装 で説明されています。
基本的な考え方は、クエリをネストされたクエリコンポーネントにラップすることです。クロージャ関数をコンポーネントの子として使用すると、あるクエリの結果を別のクエリに委任するなどの便利なことができます。

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

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>

それがあなたを助けることを願っています!

6
slorenzo

これらのクエリを個別に再利用したくない場合は、両方のクエリを1つに組み合わせて1つのリクエストを作成してください。

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

Apollo 2.xの場合:react-adoptを使用して、クエリと突然変異を単一レベルに構成できます。 (このlibは、React Context APIなどのレンダリングプロップを使用してコンポーネントを構成します。)

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

5
Luke Williams

これを回避する別の方法は、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

0
user3812429

React-apolloのcomposeを使用したクエリとミューテーション

私が結論付けたもの:

  1. Composeは、クエリをボトムアップで実行します。
  2. クエリは自動的に実行されるため、呼び出す必要はありませんが、変更を行います。
  3. Apolloチームは、誰もが作曲ではなくクエリコンポーネントを使用することを望んでいることは明らかです。したがって、後で構成を廃止する可能性があるため、提案されているクエリコンポーネントを使用することをお勧めします。

まだ構成を使用する場合のコードは次のとおりです。

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

const appQuery = gql`
    {
      apps {
        id
        name
      }
    }
  `

const subjectMutation = gql`
    mutation someName($name: String) {
      changeSubjects(name: $name) {
        subject {
          name
        }
      }
    }
  `
};

class Test extends Component {
...

  const MutationResponse = this.props.mutate({
    variables: {
      name: "some name"
    }
  })

  const QueryResponse = this.props.data.appQuery

...
}

export default compose(
  graphql(appQuery),
  graphql(subjectMutation) 
)(Test));
0
Isaac Pak