What is @apollo/react-hooks?
@apollo/react-hooks is a library that provides React hooks for interacting with Apollo Client, a comprehensive state management library for JavaScript that enables you to manage both local and remote data with GraphQL. This package allows you to easily integrate GraphQL queries, mutations, and subscriptions into your React components using hooks.
What are @apollo/react-hooks's main functionalities?
useQuery
The `useQuery` hook is used to fetch data from a GraphQL endpoint. It takes a GraphQL query as an argument and returns an object containing the loading state, any errors, and the fetched data.
import { useQuery } from '@apollo/react-hooks';
import gql from 'graphql-tag';
const GET_DOGS = gql`
query GetDogs {
dogs {
id
breed
}
}
`;
function Dogs() {
const { loading, error, data } = useQuery(GET_DOGS);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
return (
<ul>
{data.dogs.map(dog => (
<li key={dog.id}>{dog.breed}</li>
))}
</ul>
);
}
useMutation
The `useMutation` hook is used to perform GraphQL mutations. It takes a GraphQL mutation as an argument and returns a tuple containing the mutate function and an object with the mutation result.
import { useMutation } from '@apollo/react-hooks';
import gql from 'graphql-tag';
const ADD_DOG = gql`
mutation AddDog($breed: String!) {
addDog(breed: $breed) {
id
breed
}
}
`;
function AddDog() {
let input;
const [addDog, { data }] = useMutation(ADD_DOG);
return (
<div>
<form
onSubmit={e => {
e.preventDefault();
addDog({ variables: { breed: input.value } });
input.value = '';
}}
>
<input
ref={node => {
input = node;
}}
/>
<button type="submit">Add Dog</button>
</form>
</div>
);
}
useSubscription
The `useSubscription` hook is used to subscribe to GraphQL subscriptions. It takes a GraphQL subscription as an argument and returns an object containing the subscription data and loading state.
import { useSubscription } from '@apollo/react-hooks';
import gql from 'graphql-tag';
const DOG_ADDED = gql`
subscription OnDogAdded {
dogAdded {
id
breed
}
}
`;
function DogSubscription() {
const { data, loading } = useSubscription(DOG_ADDED);
if (loading) return <p>Loading...</p>;
return <p>New dog added: {data.dogAdded.breed}</p>;
}
Other packages similar to @apollo/react-hooks
react-apollo
The `react-apollo` package is the predecessor to `@apollo/react-hooks` and provides higher-order components (HOCs) and render props for integrating Apollo Client with React. While it offers similar functionality, `@apollo/react-hooks` leverages React hooks for a more modern and concise API.
urql
`urql` is a lightweight GraphQL client for React that provides hooks for querying, mutating, and subscribing to GraphQL data. It is similar to `@apollo/react-hooks` but is designed to be more modular and extensible, allowing developers to customize its behavior more easily.
relay-hooks
`relay-hooks` is a library that provides React hooks for Relay, a GraphQL client developed by Facebook. It offers similar functionality to `@apollo/react-hooks` but is designed to work with the Relay framework, which includes advanced features like data-driven dependencies and optimistic updates.
React Apollo - Hooks
React Apollo Hooks.
NOTE: Full React Apollo Hooks usage documentation is coming soon, and when ready will be made available in the main React Apollo documentation. The contents of this README are intended to help beta testers, and will change.
Contents
- Installation
- Hooks Overview
- Reference
Installation
npm install @apollo/react-hooks
Hooks Overview
Function:
export function useQuery<TData = any, TVariables = OperationVariables>(
query: DocumentNode,
options?: QueryHookOptions<TData, TVariables>
): QueryResult<TData, TVariables>;
Options:
query?: DocumentNode;
displayName?: string;
skip?: boolean;
onCompleted?: (data: TData) => void;
onError?: (error: ApolloError) => void;
ssr?: boolean;
variables?: TVariables;
fetchPolicy?: WatchQueryFetchPolicy;
errorPolicy?: ErrorPolicy;
pollInterval?: number;
client?: ApolloClient<any>;
notifyOnNetworkStatusChange?: boolean;
context?: Context;
partialRefetch?: boolean;
returnPartialData?: boolean
Result:
- client: ApolloClient;
- data: TData | undefined;
- error?: ApolloError;
- loading: boolean;
- networkStatus: NetworkStatus;
- fetchMore: any;
Example (from the Hooks demo app):
const GET_ROCKET_INVENTORY = gql`
query getRocketInventory {
rocketInventory {
id
model
year
stock
}
}
`;
export function RocketInventoryList() {
const { loading, data } = useQuery(GET_ROCKET_INVENTORY);
return (
<Row className="rocket-inventory-list mt-4">
<Col sm="12">
<h3>Available Inventory</h3>
{loading ? (
<p>Loading ...</p>
) : (
<table className="table table-striped table-bordered">
<thead>
<tr>
<th>Model</th>
<th>Year</th>
<th>Stock</th>
</tr>
</thead>
<tbody>
{data.rocketInventory.map((inventory: RocketInventory) => (
<tr
key={`${inventory.model}-${inventory.year}-${
inventory.stock
}`}
>
<td>{inventory.model}</td>
<td>{inventory.year}</td>
<td>{inventory.stock}</td>
</tr>
))}
</tbody>
</table>
)}
</Col>
</Row>
);
}
Function:
export function useMutation<TData = any, TVariables = OperationVariables>(
mutation: DocumentNode,
options?: MutationHookOptions<TData, TVariables>
): MutationTuple<TData, TVariables>;
Options:
mutation?: DocumentNode;
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;
Result:
[
(
options?: MutationFunctionOptions<TData, TVariables>
) => Promise<void | ExecutionResult<TData>>,
{
data?: TData;
error?: ApolloError;
loading: boolean;
called: boolean;
client?: ApolloClient<object>
}
];
Example (from the Hooks demo app):
const SAVE_ROCKET = gql`
mutation saveRocket($rocket: RocketInput!) {
saveRocket(rocket: $rocket) {
model
}
}
`;
export function NewRocketForm() {
const [model, setModel] = useState('');
const [year, setYear] = useState(0);
const [stock, setStock] = useState(0);
const [saveRocket, { error, data }] = useMutation<
{
saveRocket: RocketInventory;
},
{ rocket: NewRocketDetails }
>(SAVE_ROCKET, {
variables: { rocket: { model: model, year: +year, stock: +stock } },
refetchQueries: ['getRocketInventory']
});
return (
<div className="new-rocket-form mt-3">
<h3>Add a Rocket</h3>
{error ? <Alert color="danger">Oh no! {error.message}</Alert> : null}
{data && data.saveRocket ? (
<Alert color="success">
Model <strong>{data.saveRocket.model}</strong> added!
</Alert>
) : null}
<Form style={{ border: '1px solid #ddd', padding: '15px' }}>
<Row>
<Col sm="6">
<FormGroup>
<Label for="model">Model</Label>
<Input
type="text"
name="model"
id="model"
onChange={e => setModel(e.target.value)}
/>
</FormGroup>
</Col>
<Col sm="3">
<FormGroup>
<Label for="year">Year</Label>
<Input
type="number"
name="year"
id="year"
onChange={e => setYear(+e.target.value)}
/>
</FormGroup>
</Col>
<Col sm="3">
<FormGroup>
<Label for="stock">Stock</Label>
<Input
type="number"
name="stock"
id="stock"
onChange={e => setStock(+e.target.value)}
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col
sm="12"
className="text-right"
onClick={e => {
e.preventDefault();
if (model && year && stock) {
saveRocket();
}
}}
>
<Button>Add</Button>
</Col>
</Row>
</Form>
</div>
);
}
Function:
export function useSubscription<TData = any, TVariables = OperationVariables>(
subscription: DocumentNode,
options?: SubscriptionHookOptions<TData, TVariables>
);
Options:
subscription?: DocumentNode;
variables?: TVariables;
fetchPolicy?: FetchPolicy;
shouldResubscribe?: boolean | ((options: BaseSubscriptionOptions<TData, TVariables>) => boolean);
client?: ApolloClient<object>;
onSubscriptionData?: (options: OnSubscriptionDataOptions<TData>) => any;
onSubscriptionComplete?: () => void;
Example (from the Hooks demo app):
const LATEST_NEWS = gql`
subscription getLatestNews {
latestNews {
content
}
}
`;
export function LatestNews() {
const { loading, data } = useSubscription<News>(LATEST_NEWS);
return (
<Card className="bg-light">
<CardBody>
<CardTitle>
<h5>Latest News</h5>
</CardTitle>
<CardText>{loading ? 'Loading...' : data!.latestNews.content}</CardText>
</CardBody>
</Card>
);
}
Function:
export function useApolloClient(): ApolloClient<object>;
Result:
ApolloClient
instance stored in the current Context.
Example:
const client = useApolloClient();
consol.log('AC instance stored in the Context', client);
Reference