次のようなクエリファイルがあります。
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に両方のクエリが表示されるようにするにはどうすればよいですか?
私の好ましい方法は、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);
私見、最もきちんとしたソリューションの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>
);
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>
それがあなたを助けることを願っています!
これらのクエリを個別に再利用したくない場合は、両方のクエリを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);
Apollo 2.xの場合:react-adopt
を使用して、クエリと突然変異を単一レベルに構成できます。 (このlibは、React Context APIなどのレンダリングプロップを使用してコンポーネントを構成します。)
これを回避する別の方法は、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
私が結論付けたもの:
まだ構成を使用する場合のコードは次のとおりです。
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));