Невозможно объединить локальные и удаленные данные в одном запросе GraphQL (Next.js + Apollo) - PullRequest
0 голосов
/ 25 января 2019

Настройка:

Моя базовая настройка - приложение Next.js, запрашивающее данные из API GraphQL.

Я получаю массив объектов из API и могу отобразить этот массив на клиенте.

Я хочу иметь возможность фильтровать данные на основе значений Enum, определенных в схеме API. Я могу передать эти значения программно, и данные корректно обновляются.

Я хочу, чтобы эти фильтры были постоянными, когда пользователь покидает страницу и возвращается. Первоначально я планировал использовать Redux, но затем я прочитал об apollo-link-state и возможности сохранять локальное (клиентское) состояние в хранилище Apollo, поэтому я решил использовать его вместо этого. Пока все хорошо.

Проблема:

Когда я пытаюсь объединить локальный запрос и удаленный запрос в один, я получаю следующую ошибку: networkError: TypeError: Cannot read property 'some' of undefined

Мой запрос выглядит так:

const GET_COMBINED = gql`
  {
    items {
      id
      details
    }
    filters @client
  }
`

И я использую его внутри компонента, подобного этому:

export default const Items = () => (
  <Query query={GET_COMBINED}>
    {({ loading, error, data: { items, filters } }) => {
      ...do stuff...
    }}
  </Query>
)

ЕСЛИ однако , я запускаю запросы отдельно, как показано ниже:

const GET_ITEMS = gql`
  {
    items {
      id
      details
    }
  }
`
const GET_FILTERS = gql`
  {
    filters @client
  }
`

И вложенные запросы внутри компонента:

export default const Items = () => (
  <Query query={GET_ITEMS}>
    {({ loading, error, data: { items } }) => {
      return (
        <Query query={GET_FILTERS}>
          {({ data: { filters } }) => {
            ...do stuff...
          }}
        </Query>
      )
    }}
  </Query>
)

Тогда все работает как задумано!

Но, похоже, далеко не оптимально вкладывать подобные запросы, когда один запрос - по крайней мере, теоретически - выполняет свою работу. И я действительно не понимаю, почему комбинированный запрос не будет работать.

Я вычеркнул свое приложение изо всех сил, пытаясь понять, но суть его в том, что всякий раз, когда я пытаюсь объединить выборку локальных и удаленных данных в один запрос, он с треском проваливается, в то время как в изоляции оба работают нормально. .

Проблема связана с SSR / Next? Я делаю это неправильно? Заранее спасибо за помощь!

Редактировать 2 - дополнительная информация

Ошибка вызвана getDataFromTree response-apollo, однако даже когда я решаю пропустить запрос во время SSR (путем передачи пропуска ssr: false компоненту Query), комбинированный запрос все равно не выполняется. Кроме того, как удаленные, так и локальные запросы работают на стороне сервера при запуске по отдельности. Я озадачен.

Я собрал небольшой репозиторий на основе примера with-apollo от NextJS, который воспроизводит проблему здесь: https://github.com/jaxxeh/next-with-apollo-local

Когда приложение запущено, немедленное нажатие на ссылку Posts (combined) вызовет ошибку, а ссылка Posts (split) отобразит данные в соответствии с назначением.

После загрузки данных Posts (combined) покажет данные, но попытка загрузить дополнительные данные приведет к ошибке. Перезагрузка (то есть рендеринг сервера) страницы также вызовет ошибку. Флажки будут работать, и их состояние будет сохраняться во всем приложении.

Страница Posts (split) будет работать в полном соответствии с назначением Вы можете загрузить дополнительные данные поста, перезагрузить страницу и установить флажки.

Таким образом, существует очевидная проблема с комбинированным запросом, будь то на стороне сервера (ошибка при перезагрузке) или на стороне клиента (невозможно отобразить дополнительные сообщения). Однако прямая запись в локальное состояние (которое вообще игнорирует запрос) работает.

Я удалил исходный код Apollo для краткости и ясности, он доступен в репозитории, указанном выше. Спасибо.

1 Ответ

0 голосов
/ 26 января 2019

Добавьте пустой объект в качестве вашей карты преобразователя в конфигурацию, которую вы передаете withClientState:

const stateLink = withClientState({
  cache,
  defaults: {
    filters: ['A', 'B', 'C', 'D']
  },
  resolvers: {},
  typedefs: `
    type Query {
      filters: [String!]!
    }
  `,
})

Здесь есть проблема здесь . Было бы замечательно, если бы конструктор выдавал какую-то ошибку, если опция отсутствовала, или если документы были яснее об этом.

...