Локальное состояние Аполлона - запрос объекта с неизвестными ключами - PullRequest
1 голос
/ 19 июня 2019

Я пытаюсь добавить Аполлона в приложение. Я буду использовать его для извлечения данных и хочу следовать передовым методам и использовать новый API (начиная с Apollo 2.5) для хранения локального состояния пользовательского интерфейса.

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

Я хочу портировать через шаблон, который я использовал в приложениях Redux, где значения многих элементов пользовательского интерфейса хранятся централизованно. В Redux у меня был объект-редуктор, в котором хранились мои значения пользовательского интерфейса, и он выглядел так:

{
  dropdowns: {
    someDropdown: [{ index: 0, value: 'Selected Value' }]
  },
  checkboxes: {
    someCheckbox: true
  }
}

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

Я также открыт для упрощенной версии выше, где нет подкатегорий по типу элемента пользовательского интерфейса.

У меня также был отдельный редуктор, хранящий состояние некоторых элементов пользовательского интерфейса, например:

{
  openDropdownId: 'someDropdown',
  openModalId: null
}

Важно отметить, что эти данные включают объекты, ключи которых непредсказуемы. Я не уверен, как печатать это с помощью gql, и не уверен, как эффективно извлечь эти данные (см. Нижнюю часть вопроса).

Я пытался воспроизвести это с помощью Apollo Client, но наткнулся на массу ошибок. Вот моя настройка клиента:

Например, для раскрывающегося списка идея состоит в том, что states здесь хранит открытое / закрытое состояние, тогда как values хранит информацию о выбранном значении.

import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import gql from 'graphql-tag';

const typeDefs = gql`
  extend type UI {
    states: Object
    values: Object
  }
`;

const defaults = {
  ui: {
    __typename: 'UI',
    states: {},
    values: {}
  }
};

const cache = new InMemoryCache();
const client = new ApolloClient({
  cache,
  resolvers: {},
  typeDefs
});

console.log({ defaults });
cache.writeData({ data: defaults });

export default client;

Тогда я использую этот клиент так:

<ApolloProvider client={client}>
  <App />
</ApolloProvider>

А вот пример запроса, который выдает ошибку:

const QUERY = gql`
  {
    ui @client {
      states
      values
    }
  }
`;

Я вижу следующие ошибки:

  • Uncaught Invariant Violation: Missing selection set for object of type undefined returned for query field states

Эта ошибка появляется в компоненте Query.

Я также получаю два предупреждения (вероятно, одно для states и одно для values), что:

  • Missing field __typename in {}

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


Дополнительный вопрос: если у компонента есть UID, было бы неплохо иметь возможность запрашивать его значения, например:

const QUERY = gql`
  {
    ui @client {
      states {
        ${uid}
      }
      values {
        ${uid}
      }
    }
  }
`;

Вместо получения всех значений пользовательского интерфейса и последующего поиска соответствующего в компоненте.

Это выдает ошибку, однако:

Syntax Error: Invalid number, expected digit but got: "d".

Есть ли способ выполнить такой запрос или лучший способ справиться со всем этим? Хотя эта структура данных может и не быть идиоматичной, похоже, что Apollo должен поддерживать это для отфильтрованных запросов, не так ли?

...