React integration for Apollo GraphQL client with hooks, components, and HOCs.
npx @tessl/cli install tessl/npm-react-apollo@3.1.0React Apollo is a comprehensive library that integrates React with Apollo GraphQL client, providing multiple patterns for data fetching: modern React hooks, render prop components, higher-order components, server-side rendering utilities, and testing tools.
npm install react-apollo apollo-client graphqlimport {
// Hooks
useQuery,
useLazyQuery,
useMutation,
useSubscription,
useApolloClient,
// Components
Query,
Mutation,
Subscription,
// HOCs
graphql,
withQuery,
withMutation,
withSubscription,
withApollo,
// Context
ApolloProvider,
ApolloConsumer,
getApolloContext,
resetApolloContext,
// SSR
getDataFromTree,
renderToStringWithData,
// Types
QueryResult,
MutationResult,
SubscriptionResult,
OperationVariables
} from "react-apollo";For CommonJS:
const {
useQuery,
useLazyQuery,
useMutation,
useSubscription,
useApolloClient,
Query,
Mutation,
Subscription,
graphql,
withQuery,
withMutation,
withSubscription,
withApollo,
ApolloProvider,
ApolloConsumer
} = require("react-apollo");import React from "react";
import { ApolloProvider, useQuery, useMutation } from "react-apollo";
import ApolloClient from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import { HttpLink } from "apollo-link-http";
import gql from "graphql-tag";
// Setup Apollo Client
const client = new ApolloClient({
cache: new InMemoryCache(),
link: new HttpLink({
uri: "https://api.example.com/graphql"
})
});
const GET_USERS = gql`
query GetUsers {
users {
id
name
email
}
}
`;
const CREATE_USER = gql`
mutation CreateUser($input: UserInput!) {
createUser(input: $input) {
id
name
email
}
}
`;
// Component using hooks
function UserList() {
const { data, loading, error } = useQuery(GET_USERS);
const [createUser] = useMutation(CREATE_USER);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
const handleCreateUser = async () => {
await createUser({
variables: {
input: { name: "New User", email: "new@example.com" }
}
});
};
return (
<div>
<button onClick={handleCreateUser}>Add User</button>
<ul>
{data.users.map((user) => (
<li key={user.id}>{user.name} - {user.email}</li>
))}
</ul>
</div>
);
}
// App with Apollo Provider
function App() {
return (
<ApolloProvider client={client}>
<UserList />
</ApolloProvider>
);
}React Apollo provides multiple integration patterns for different use cases:
useQuery, useMutation, useSubscriptionQuery, Mutation, Subscription) using children render functionsgraphql, withQuery, withMutation HOCsModern React hook-based interface for GraphQL operations with automatic re-rendering and state management.
function useQuery<TData = any, TVariables = OperationVariables>(
query: DocumentNode,
options?: QueryHookOptions<TData, TVariables>
): QueryResult<TData, TVariables>;
function useMutation<TData = any, TVariables = OperationVariables>(
mutation: DocumentNode,
options?: MutationHookOptions<TData, TVariables>
): MutationTuple<TData, TVariables>;
function useSubscription<TData = any, TVariables = OperationVariables>(
subscription: DocumentNode,
options?: SubscriptionHookOptions<TData, TVariables>
): SubscriptionResult<TData>;Render prop components for declarative GraphQL operations with flexible rendering patterns.
function Query<TData = any, TVariables = OperationVariables>(
props: QueryComponentOptions<TData, TVariables>
): JSX.Element | null;
function Mutation<TData = any, TVariables = OperationVariables>(
props: MutationComponentOptions<TData, TVariables>
): JSX.Element | null;
function Subscription<TData = any, TVariables = OperationVariables>(
props: SubscriptionComponentOptions<TData, TVariables>
): JSX.Element | null;Class-based integration patterns with HOCs that inject GraphQL data and functionality as props.
function graphql<TProps = {}, TData = {}, TGraphQLVariables = {}, TChildProps = {}>(
document: DocumentNode,
operationOptions?: OperationOption<TProps, TData, TGraphQLVariables, TChildProps>
): (WrappedComponent: React.ComponentType<TChildProps>) => React.ComponentType<TProps>;
function withQuery<TProps = {}, TData = {}, TGraphQLVariables = {}>(
document: DocumentNode,
operationOptions?: OperationOption<TProps, TData, TGraphQLVariables>
): (WrappedComponent: React.ComponentType) => React.ComponentType<TProps>;
function withApollo<TProps>(
WrappedComponent: React.ComponentType<WithApolloClient<TProps>>
): React.ComponentType<TProps>;React Apollo Higher-Order Components
SSR utilities for data fetching and HTML generation on the server with complete GraphQL data preloading.
function getDataFromTree(
tree: React.ReactNode,
context?: { [key: string]: any }
): Promise<string>;
function renderToStringWithData(
component: React.ReactElement<any>
): Promise<string>;
function getMarkupFromTree(options: GetMarkupFromTreeOptions): Promise<string>;React Apollo Server-Side Rendering
Comprehensive testing tools with mocking capabilities for GraphQL operations and component testing.
function MockedProvider<TSerializedCache = {}>(
props: MockedProviderProps<TSerializedCache>
): React.ReactElement;
function MockLink(
mocks: ReadonlyArray<MockedResponse>,
addTypename?: boolean
): ApolloLink;
function createClient(config?: any): ApolloClient<any>;
function wait(milliseconds?: number): Promise<void>;React context integration for Apollo Client instances with provider/consumer patterns.
interface ApolloContextValue {
client?: ApolloClient<object>;
renderPromises?: Record<any, any>;
}
const ApolloProvider: React.FC<ApolloProviderProps<any>>;
const ApolloConsumer: React.FC<ApolloConsumerProps>;
function getApolloContext(): React.Context<ApolloContextValue>;
function resetApolloContext(): void;Usage Example:
import React from "react";
import { ApolloProvider, ApolloConsumer } from "react-apollo";
import ApolloClient from "apollo-client";
const client = new ApolloClient({
// client configuration
});
function App() {
return (
<ApolloProvider client={client}>
<div>
<ApolloConsumer>
{(client) => (
<button onClick={() => client.clearStore()}>
Clear Cache
</button>
)}
</ApolloConsumer>
</div>
</ApolloProvider>
);
}type OperationVariables = Record<string, any>;
type Context = Record<string, any>;
interface ExecutionResult<T = Record<string, any>> {
data?: T;
extensions?: Record<string, any>;
errors?: GraphQLError[];
}
interface QueryResult<TData = any, TVariables = OperationVariables>
extends ObservableQueryFields<TData, TVariables> {
client: ApolloClient<any>;
data: TData | undefined;
error?: ApolloError;
loading: boolean;
networkStatus: NetworkStatus;
called: boolean;
}
interface MutationResult<TData = any> {
data?: TData;
error?: ApolloError;
loading: boolean;
called: boolean;
client?: ApolloClient<object>;
}
interface SubscriptionResult<TData = any> {
loading: boolean;
data?: TData;
error?: ApolloError;
}
type MutationFunction<TData = any, TVariables = OperationVariables> = (
options?: MutationFunctionOptions<TData, TVariables>
) => Promise<MutationFetchResult<TData>>;type MutationTuple<TData, TVariables> = [
(options?: MutationFunctionOptions<TData, TVariables>) => Promise<ExecutionResult<TData>>,
MutationResult<TData>
];
type QueryTuple<TData, TVariables> = [
(options?: QueryLazyOptions<TVariables>) => void,
QueryResult<TData, TVariables>
];
interface QueryHookOptions<TData = any, TVariables = OperationVariables>
extends QueryFunctionOptions<TData, TVariables> {
query?: DocumentNode;
}
interface MutationHookOptions<TData = any, TVariables = OperationVariables>
extends BaseMutationOptions<TData, TVariables> {
mutation?: DocumentNode;
}
interface SubscriptionHookOptions<TData = any, TVariables = OperationVariables>
extends BaseSubscriptionOptions<TData, TVariables> {
subscription?: DocumentNode;
}interface QueryComponentOptions<TData = any, TVariables = OperationVariables>
extends QueryFunctionOptions<TData, TVariables> {
children: (result: QueryResult<TData, TVariables>) => JSX.Element | null;
query: DocumentNode;
}
interface MutationComponentOptions<TData = any, TVariables = OperationVariables>
extends BaseMutationOptions<TData, TVariables> {
mutation: DocumentNode;
children: (
mutateFunction: MutationFunction<TData, TVariables>,
result: MutationResult<TData>
) => JSX.Element | null;
}
interface SubscriptionComponentOptions<TData = any, TVariables = OperationVariables>
extends BaseSubscriptionOptions<TData, TVariables> {
subscription: DocumentNode;
children?: null | ((result: SubscriptionResult<TData>) => JSX.Element | null);
}interface BaseQueryOptions<TVariables = OperationVariables> {
ssr?: boolean;
variables?: TVariables;
fetchPolicy?: WatchQueryFetchPolicy;
errorPolicy?: ErrorPolicy;
pollInterval?: number;
client?: ApolloClient<any>;
notifyOnNetworkStatusChange?: boolean;
context?: Context;
partialRefetch?: boolean;
returnPartialData?: boolean;
}
interface QueryFunctionOptions<TData = any, TVariables = OperationVariables>
extends BaseQueryOptions<TVariables> {
displayName?: string;
skip?: boolean;
onCompleted?: (data: TData) => void;
onError?: (error: ApolloError) => void;
}
interface BaseMutationOptions<TData = any, TVariables = OperationVariables> {
variables?: TVariables;
optimisticResponse?: TData | ((vars: TVariables) => TData);
refetchQueries?: Array<string | PureQueryOptions> | RefetchQueriesFunction;
awaitRefetchQueries?: boolean;
errorPolicy?: ErrorPolicy;
update?: MutationUpdaterFn<TData>;
client?: ApolloClient<object>;
notifyOnNetworkStatusChange?: boolean;
context?: Context;
onCompleted?: (data: TData) => void;
onError?: (error: ApolloError) => void;
fetchPolicy?: WatchQueryFetchPolicy;
ignoreResults?: boolean;
}
interface BaseSubscriptionOptions<TData = any, TVariables = OperationVariables> {
variables?: TVariables;
fetchPolicy?: FetchPolicy;
shouldResubscribe?: boolean | ((options: BaseSubscriptionOptions<TData, TVariables>) => boolean);
client?: ApolloClient<object>;
skip?: boolean;
onSubscriptionData?: (options: OnSubscriptionDataOptions<TData>) => any;
onSubscriptionComplete?: () => void;
}