Я пытаюсь добавить Аполлона в приложение. Я буду использовать его для извлечения данных и хочу следовать передовым методам и использовать новый 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 должен поддерживать это для отфильтрованных запросов, не так ли?