React Apollo hooks provide a modern React interface for GraphQL operations using React's hook system. These hooks offer data fetching, mutation execution, and subscription management.
Hook for executing GraphQL queries with React's hook system.
/**
* Execute a GraphQL query with React hook
* @param query - GraphQL query document
* @param options - Query configuration options
* @returns Query result with data, loading state, and error
*/
function useQuery<TData = any, TVariables = OperationVariables>(
query: DocumentNode,
options?: QueryHookOptions<TData, TVariables>
): QueryResult<TData, TVariables>;
interface QueryHookOptions<TData = any, TVariables = OperationVariables>
extends QueryFunctionOptions<TData, TVariables> {
query?: DocumentNode;
}Usage Examples:
import { useQuery } from "react-apollo";
import gql from "graphql-tag";
const GET_USERS = gql`
query GetUsers($limit: Int) {
users(limit: $limit) {
id
name
email
}
}
`;
function UserList() {
const { data, loading, error } = useQuery(GET_USERS, {
variables: { limit: 10 },
fetchPolicy: "cache-and-network"
});
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<ul>
{data.users.map((user) => (
<li key={user.id}>{user.name} - {user.email}</li>
))}
</ul>
);
}Hook for manually triggered GraphQL queries that don't execute automatically.
/**
* Create a lazy query that can be triggered manually
* @param query - GraphQL query document
* @param options - Query configuration options
* @returns Tuple with query function and result
*/
function useLazyQuery<TData = any, TVariables = OperationVariables>(
query: DocumentNode,
options?: LazyQueryHookOptions<TData, TVariables>
): QueryTuple<TData, TVariables>;
type QueryTuple<TData, TVariables> = [
(options?: QueryLazyOptions<TVariables>) => void,
QueryResult<TData, TVariables>
];
interface LazyQueryHookOptions<TData = any, TVariables = OperationVariables>
extends Omit<QueryFunctionOptions<TData, TVariables>, 'skip'> {
query?: DocumentNode;
}Usage Examples:
import { useLazyQuery } from "react-apollo";
import gql from "graphql-tag";
const SEARCH_USERS = gql`
query SearchUsers($searchTerm: String!) {
searchUsers(term: $searchTerm) {
id
name
email
}
}
`;
function UserSearch() {
const [searchUsers, { data, loading, error }] = useLazyQuery(SEARCH_USERS);
const handleSearch = (term: string) => {
searchUsers({ variables: { searchTerm: term } });
};
return (
<div>
<input
type="text"
onChange={(e) => handleSearch(e.target.value)}
placeholder="Search users..."
/>
{loading && <div>Searching...</div>}
{data && (
<ul>
{data.searchUsers.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)}
</div>
);
}Hook for executing GraphQL mutations with optimistic updates and cache management.
/**
* Execute GraphQL mutations with React hook
* @param mutation - GraphQL mutation document
* @param options - Mutation configuration options
* @returns Tuple with mutation function and result
*/
function useMutation<TData = any, TVariables = OperationVariables>(
mutation: DocumentNode,
options?: MutationHookOptions<TData, TVariables>
): MutationTuple<TData, TVariables>;
type MutationTuple<TData, TVariables> = [
(options?: MutationFunctionOptions<TData, TVariables>) => Promise<ExecutionResult<TData>>,
MutationResult<TData>
];
interface MutationHookOptions<TData = any, TVariables = OperationVariables>
extends BaseMutationOptions<TData, TVariables> {
mutation?: DocumentNode;
}Usage Examples:
import { useMutation } from "react-apollo";
import gql from "graphql-tag";
const CREATE_USER = gql`
mutation CreateUser($input: UserInput!) {
createUser(input: $input) {
id
name
email
}
}
`;
function CreateUserForm() {
const [createUser, { data, loading, error }] = useMutation(CREATE_USER, {
onCompleted: (data) => {
console.log('User created:', data.createUser);
},
onError: (error) => {
console.error('Error creating user:', error);
}
});
const handleSubmit = async (formData) => {
try {
await createUser({
variables: { input: formData },
optimisticResponse: {
createUser: {
__typename: 'User',
id: 'temp-id',
...formData
}
}
});
} catch (err) {
// Error handled by onError callback
}
};
return (
<form onSubmit={handleSubmit}>
{/* Form fields */}
<button type="submit" disabled={loading}>
{loading ? 'Creating...' : 'Create User'}
</button>
{error && <div>Error: {error.message}</div>}
</form>
);
}Hook for managing GraphQL subscriptions with real-time data updates.
/**
* Execute GraphQL subscriptions with React hook
* @param subscription - GraphQL subscription document
* @param options - Subscription configuration options
* @returns Subscription result with data and loading state
*/
function useSubscription<TData = any, TVariables = OperationVariables>(
subscription: DocumentNode,
options?: SubscriptionHookOptions<TData, TVariables>
): SubscriptionResult<TData>;
interface SubscriptionHookOptions<TData = any, TVariables = OperationVariables>
extends BaseSubscriptionOptions<TData, TVariables> {
subscription?: DocumentNode;
}Usage Examples:
import { useSubscription } from "react-apollo";
import gql from "graphql-tag";
const MESSAGE_SUBSCRIPTION = gql`
subscription OnMessageAdded($channelId: ID!) {
messageAdded(channelId: $channelId) {
id
content
user {
name
}
createdAt
}
}
`;
function ChatMessages({ channelId }) {
const { data, loading } = useSubscription(MESSAGE_SUBSCRIPTION, {
variables: { channelId },
onSubscriptionData: ({ subscriptionData }) => {
console.log('New message:', subscriptionData.data.messageAdded);
}
});
if (loading) return <div>Connecting...</div>;
return (
<div>
{data && (
<div className="new-message">
<strong>{data.messageAdded.user.name}:</strong>
<p>{data.messageAdded.content}</p>
</div>
)}
</div>
);
}Hook for accessing the Apollo Client instance directly.
/**
* Access Apollo Client instance in components
* @returns Apollo Client instance
*/
function useApolloClient(): ApolloClient<object>;Usage Examples:
import { useApolloClient } from "react-apollo";
function DataManager() {
const client = useApolloClient();
const handleClearCache = () => {
client.clearStore();
};
const handleRefreshCache = () => {
client.reFetchObservableQueries();
};
const handleDirectQuery = async () => {
const result = await client.query({
query: GET_USER_QUERY,
variables: { id: '123' },
fetchPolicy: 'network-only'
});
console.log('Direct query result:', result.data);
};
return (
<div>
<button onClick={handleClearCache}>Clear Cache</button>
<button onClick={handleRefreshCache}>Refresh Cache</button>
<button onClick={handleDirectQuery}>Direct Query</button>
</div>
);
}type CommonOptions<TOptions> = TOptions & {
client?: ApolloClient<object>;
};
interface QueryPreviousData<TData, TVariables> {
client?: ApolloClient<object>;
query?: DocumentNode;
variables?: TVariables;
}
interface QueryCurrentObservable<TData, TVariables> {
currentObservable?: ObservableQuery<TData, TVariables>;
}
interface MutationOptions<TData = any, TVariables = OperationVariables>
extends BaseMutationOptions<TData, TVariables> {
mutation?: DocumentNode;
}
interface SubscriptionOptions<TData = any, TVariables = OperationVariables>
extends BaseSubscriptionOptions<TData, TVariables> {
subscription?: DocumentNode;
}
interface SubscriptionCurrentObservable<TData, TVariables> {
currentObservable?: Observable<FetchResult<TData>>;
}