Как связать два запроса 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 и составить? Или есть другой способ сделать это? Заранее спасибо.

Ответ 1

Подставки, добавленные вашим компонентом 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 })

Ответ 2

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

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

пример кода:

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