Как связать два запроса GraphQL последовательно с помощью Apollo Client

Я использую Apollo Client для внешнего интерфейса и Graphcool для внутреннего интерфейса. Есть два запроса firstQuery и secondQuery, которые я хочу, чтобы они вызывались последовательно при открытии страницы. Вот пример кода (определение компонента TestPage здесь не указано):

export default compose(
        graphql(firstQuery, {
            name: 'firstQuery'
        }),
        graphql(secondQuery, { 
            name: 'secondQuery' ,
            options: (ownProps) => ({
                variables: {
                   var1: *getValueFromFirstQuery*
                }
            })
        })
)(withRouter(TestPage))

Мне нужно получить var1 в secondQuery из результата firstQuery. Как я могу сделать это с помощью Apollo Client и сочинить? Или есть другой способ сделать это? Заранее спасибо.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Что такое Apollo Client и зачем он нужен?
Что такое Apollo Client и зачем он нужен?
Apollo Client - это полнофункциональный клиент GraphQL для JavaScript-приложений, который упрощает получение, управление и обновление данных в...
24
0
13 138
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Свойства, добавленные вашим компонентом firstQuery, будут доступны для компонента ниже (внутри), поэтому вы можете сделать что-то вроде:

export default compose(
  graphql(firstQuery, {
    name: 'firstQuery'
  }),
  graphql(secondQuery, { 
    name: 'secondQuery',
    skip: ({ firstQuery }) => !firstQuery.data,
    options: ({firstQuery}) => ({
      variables: {
          var1: firstQuery.data.someQuery.someValue
      }
    })
  })
)(withRouter(TestPage))

Обратите внимание, что мы используем skip, чтобы пропустить второй запрос, если у нас нет данных из первого запроса для работы.

Использование компонента запроса

Если вы используете компонент Query, вы также можете использовать свойство skip, хотя у вас также есть возможность вернуть что-то еще (например, null или индикатор загрузки) внутри первой функции рендеринга реквизита:

<Query query = {firstQuery}>
  {({ data: { someQuery: { someValue } = {} } = {} }) => (
    <Query
      query = {secondQuery}
      variables = {{var1: someValue}}
      skip = {someValue === undefined}
    >
      {({ data: secondQueryData }) => (
        // your component here
      )}
</Query>

Использование хука useQuery

Вы также можете использовать skip с перехватчиком useQuery:

const { data: { someQuery: { someValue } = {} } = {} } = useQuery(firstQuery)
const variables = { var1: someValue }
const skip = someValue === undefined
const { data: secondQueryData } = useQuery(secondQuery, { variables, skip })

Мутации

В отличие от запросов, мутации включают в себя специальный вызов функции для запуска запроса. Эта функция возвращает обещание, которое будет разрешено с результатами мутации. Это означает, что при работе с мутациями вы можете просто связать полученные обещания:

const [doA] = useMutation(MUTATION_A)
const [doB] = useMutation(MUTATION_B)

// elsewhere
const { data: { someValue } } = await doA()
const { data: { someResult } } = await doB({ variables: { someValue } })

Работайте как шарм! Спасибо, Даниэль. Странно, что нигде не нашел документации по этому поводу.

afterglowlee 16.03.2018 15:02

Не могу поверить, что это работает. Ничего не могу найти больше нигде

Varun Singh 08.01.2019 21:57

Тот же подход работает для всех, кто использует реагировать на хуки аполлона.

Вы можете использовать два перехватчика useQuery и передать результат первого запроса в skipoption второго,

пример кода:

const AlertToolbar = ({ alertUid }: AlertToolbarProps) => {
  const authenticationToken = useSelectAuthenticationToken()

  const { data: data1 } = useQuery<DataResponse>(query, {
    skip: !authenticationToken,
    variables: {
      alertUid,
    },
    context: makeContext(authenticationToken),
  })

  const { data: data2, error: error2 } = useQuery<DataResponse2>(query2, {
    skip:
      !authenticationToken ||
      !data1 ||
      !data1.alertOverview ||
      !data1.alertOverview.deviceId,
    variables: {
      deviceId:
        data1 && data1.alertOverview ? data1.alertOverview.deviceId : null,
    },
    context: makeContext(authenticationToken),
  })

  if (error2 || !data2 || !data2.deviceById || !data2.deviceById.id) {
    return null
  }
  const { deviceById: device } = data2
  return (
    <Toolbar>
    ...
    // do some stuff here with data12

Другие вопросы по теме