react-apollo-network-status
Brings information about the global network status from Apollo into React.

This library helps with implementing global loading indicators like progress bars or adding global error handling, so you don't have to respond to every error in a component that invokes an operation.
Apollo Client version compatibility
Usage
import React from 'react';
import ReactDOM from 'react-dom';
import {ApolloClient, InMemoryCache, HttpLink} from '@apollo/client';
import {ApolloProvider} from '@apollo/client/react';
import {createNetworkStatusNotifier} from 'react-apollo-network-status';
const {link, useApolloNetworkStatus} = createNetworkStatusNotifier();
function GlobalLoadingIndicator() {
const status = useApolloNetworkStatus();
if (status.numPendingQueries > 0) {
return <p>Loading …</p>;
} else {
return null;
}
}
const client = new ApolloClient({
cache: new InMemoryCache(),
link: link.concat(createHttpLink())
});
const element = (
<ApolloProvider client={client}>
<GlobalLoadingIndicator />
<App />
</ApolloProvider>
);
ReactDOM.render(element, document.getElementById('root'));
Returned data
The hook useApolloNetworkStatus provides an object with the following properties:
type NetworkStatus = {
numPendingQueries: number;
numPendingMutations: number;
queryError?: OperationError;
mutationError?: OperationError;
};
type OperationError = {
networkError?: Error | ServerError | ServerParseError;
operation: ApolloLink.Operation;
response?: FormattedExecutionResult;
graphQLErrors?: ReadonlyArray<GraphQLFormattedError>;
};
Subscriptions currently don't affect the status returned by useApolloNetworkStatus.
Useful applications are for example integrating with NProgress.js or showing errors with snackbars from Material UI.
Advanced usage
Limit handling to specific operations
The default configuration enables an opt-out behaviour per operation by setting a context variable:
mutate({context: {useApolloNetworkStatus: false}});
You can configure an opt-in behaviour by specifying an operation whitelist like this:
useApolloNetworkStatus({
shouldHandleOperation: (operation: Operation) =>
operation.getContext().useApolloNetworkStatus === true
});
mutate({context: {useApolloNetworkStatus: true}});
Custom state
You can fully control how operations are mapped to state by providing a custom reducer to a separate low-level hook.
const {link, useApolloNetworkStatusReducer} = createNetworkStatusNotifier();
const initialState = 0;
function reducer(state: number, action: NetworkStatusAction) {
switch (action.type) {
case ActionTypes.REQUEST:
return state + 1;
case ActionTypes.ERROR:
case ActionTypes.SUCCESS:
case ActionTypes.CANCEL:
return state - 1;
}
}
function GlobalLoadingIndicator() {
const numPendingQueries = useApolloNetworkStatusReducer(reducer, initialState);
return <p>Pending queries: {numPendingQueries}</p>;
}