prostore-apollo-react
Адаптер для
prostore
, связывающий
prostore-apollo
и
prostore-react.
Содержит две полезных фичи:
ApolloClientsContext
- прокидывание клиента Apollo через контекстuseGraphqlQuery
/ useGraphqlWatchQuery
- хуки, которые
динамически создают GraphqlQueryStore в соответствии с переданными
параметрами и подписывают на него компонент.
ApolloClientsContext
Позволяет прокидывать клиент аполло через контекст реакта.
Таким образом реализуется принцип Dependency Injection и
снижается связанность кода.
import { ApolloClient } from 'apollo-client';
import {
ApolloClientsContext,
ApolloClientsManager
} from '@proscom/prostore-apollo-react';
import { App } from './App';
const apolloClient = new ApolloClient();
const apolloClient2 = new ApolloClient();
const apolloContext = new ApolloClientsManager({
default: apolloClient,
specific: apolloClient2
});
const rootElement = document.getElementById('root');
ReactDOM.render(
<ApolloClientsContext.Provider value={apolloContext}>
<App />
</ApolloClientsContext.Provider>,
rootElement
);
function App() {
const defaultClient = useContextApolloClient();
const specificClient = useContextApolloClient('specific');
}
useGraphqlQuery
/ useGraphqlWatchQuery
Эти хуки динамически создают стор GraphqlQueryStore / GraphqlWatchQueryStore
в соответствии с параметрами конструктора, переданными в queryOptions,
и подписывают компонент на этот стор с помощью
useRequestStore
.
useGraphqlQuery
и useGraphqlWatchQuery
отличаются только поведением.
API у них одинаковое. useGraphqlWatchQuery
использует watchQuery
из Apollo. Таким образом он подписывается на последующие обновления
кеша Apollo после первоначального выполнения запроса.
Кеш Apollo обновляется например при рефетче после мутаций или
при ручном удалении из него каких-то данных.
const query = gql`
query getUser($id: ID) {
user(id: $id) {
id
name
}
}
`;
const queryOptions = {
query,
mapData: (result) => result.user,
skipQuery: skipIfNull(null)
};
function UserInfo({ id }) {
const userQuery = useGraphqlWatchQuery({
queryOptions,
variables: { id },
client,
options
});
const userData = userQuery.state.data;
if (userQuery.check.spinner) {
return <Spinner />;
} else if (userQuery.check.error) {
return <ErrorMessage error={userQuery.state.error} />;
}
return <div>{userData.name}</div>;
}
Так как useGraphqlQuery
/ useGraphqlWatchQuery
создают
стор внутри компонента, то при ремаунте компонента стор будет
создан заново. Это не приводит к повторным запросам на бекенд,
так как результат запроса уже сохранен в кеше Apollo.