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);
тогда это работает, но у меня нет другого запроса. Да, я тестировал оба отдельно, и они работают. Как мне сделать так, чтобы оба запроса в реквизит.Дейта?
6 ответов
мой предпочтительный способ-использовать compose
функциональность клиента apollo (docu).
изменить: Если у вас есть более одного запроса, вы должны назвать их.
Так что в вашем случае это может выглядеть так:
import React, {Component} from 'react'
import queries from './queries'
import { 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);
Если вы не хотите повторно использовать любой из этих запросов независимо, почему бы не сделать один запрос, объединив оба запроса в одном i.e:
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);
на Аполлон 2.x: вы можете использовать react-adopt
чтобы составить запросы и мутации в один уровень. (Этот lib будет составлять любые компоненты с реквизитом рендеринга,например API контекста React.)
IMHO, одно из самых аккуратных решений описано в реализация реакции клиента Apollo.
Основная идея заключается в том, чтобы обернуть ваши запросы во вложенные компоненты запросов. Использование функций закрытия в качестве дочерних компонентов позволяет легко делегировать результаты одного запроса в другой запрос и т. д.
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>
);
другой способ обойти это, чтобы использовать .
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 { 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>
надеюсь, это тебе поможет!