Product
Introducing License Enforcement in Socket
Ensure open-source compliance with Socket’s License Enforcement Beta. Set up your License Policy and secure your software!
@apollo/client
Advanced tools
The @apollo/client npm package is a comprehensive state management library for JavaScript that enables you to manage both local and remote data with GraphQL. It is designed to help you develop faster and more secure apps with less boilerplate. It integrates seamlessly with any JavaScript front-end, allowing for reactive data fetching, caching, and data management.
Fetching data with useQuery
This feature allows you to fetch data from a GraphQL server. The useQuery hook is used to execute a GraphQL query and handle loading, error, and result states.
import { useQuery, gql } from '@apollo/client';
const GET_LAUNCHES = gql`
query GetLaunches {
launches {
id
mission_name
}
}
`;
function Launches() {
const { loading, error, data } = useQuery(GET_LAUNCHES);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
return data.launches.map(({ id, mission_name }) => (
<div key={id}>
<p>{mission_name}</p>
</div>
));
}
Updating data with useMutation
This feature enables you to update data on a GraphQL server. The useMutation hook is used to execute a mutation, allowing you to create, update, or delete data.
import { useMutation, gql } from '@apollo/client';
const ADD_TODO = gql`
mutation AddTodo($type: String!) {
addTodo(type: $type) {
id
type
}
}
`;
function AddTodo() {
let input;
const [addTodo, { data }] = useMutation(ADD_TODO);
return (
<div>
<form
onSubmit={e => {
e.preventDefault();
addTodo({ variables: { type: input.value } });
input.value = '';
}}
>
<input
ref={node => {
input = node;
}}
/>
<button type="submit">Add Todo</button>
</form>
</div>
);
}
Managing local state
This feature allows you to manage local state using Apollo Client. You can read and write to the cache as if it were a local database, enabling you to manage client-side state alongside remote data.
import { gql, useApolloClient } from '@apollo/client';
const GET_LOCAL_STATE = gql`
query GetLocalState {
isLoggedIn @client
}
`;
function LoginButton() {
const client = useApolloClient();
const data = client.readQuery({ query: GET_LOCAL_STATE });
const isLoggedIn = data.isLoggedIn;
return (
<button onClick={() => {
client.writeQuery({
query: GET_LOCAL_STATE,
data: { isLoggedIn: !isLoggedIn }
});
}}>
{isLoggedIn ? 'Log out' : 'Log in'}
</button>
);
}
Relay is a JavaScript framework for building data-driven React applications with GraphQL. It is similar to @apollo/client in that it provides a powerful and efficient way to fetch and manage GraphQL data. Relay focuses on performance optimizations and static query generation, which can make it more suitable for complex, large-scale applications with high performance requirements.
urql is a highly customizable and versatile GraphQL client for React, Vue, Svelte, and other JavaScript frameworks. It offers a simpler and more flexible approach compared to @apollo/client, with features like document caching and subscriptions. urql's extensibility and plugin system make it a good choice for developers looking for a lightweight and adaptable GraphQL client.
Apollo Client is a fully-featured caching GraphQL client with integrations for React, Angular, and more. It allows you to easily build UI components that fetch data via GraphQL.
☑️ Apollo Client User Survey |
---|
What do you like best about Apollo Client? What needs to be improved? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Client usage and allow us to serve you better. |
All Apollo Client documentation, including React integration articles and helpful recipes, can be found at:
https://www.apollographql.com/docs/react/
The Apollo Client API reference can be found at:
https://www.apollographql.com/docs/react/api/apollo-client/
Learn how to use Apollo Client with self-paced hands-on training on Odyssey, Apollo's official learning platform:
https://odyssey.apollographql.com/
Name | Username |
---|---|
Ben Newman | @benjamn |
Alessia Bellisario | @alessbell |
Jeff Auriemma | @bignimbus |
Hugh Willson | @hwillson |
Jerel Miller | @jerelmiller |
Lenz Weber-Tronic | @phryneas |
Apollo builds open-source software and a graph platform to unify GraphQL across your apps and services. We help you ship faster with:
Check out the Odyssey learning platform, the perfect place to start your GraphQL journey with videos and interactive code challenges. Join the Apollo Community to interact with and get technical help from the GraphQL community.
3.9.0
#11424 62f3b6d
Thanks @phryneas! - Simplify RetryLink, fix potential memory leak
Historically, RetryLink
would keep a values
array of all previous values, in case the operation would get an additional subscriber at a later point in time.
In practice, this could lead to a memory leak (#11393) and did not serve any further purpose, as the resulting observable would only be subscribed to by Apollo Client itself, and only once - it would be wrapped in a Concast
before being exposed to the user, and that Concast
would handle subscribers on its own.
#11435 5cce53e
Thanks @phryneas! - Deprecates canonizeResults
.
Using canonizeResults
can result in memory leaks so we generally do not recommend using this option anymore. A future version of Apollo Client will contain a similar feature without the risk of memory leaks.
#11254 d08970d
Thanks @benjamn! - Decouple canonicalStringify
from ObjectCanon
for better time and memory performance.
#11356 cc4ac7e
Thanks @phryneas! - Fix a potential memory leak in FragmentRegistry.transform
and FragmentRegistry.findFragmentSpreads
that would hold on to passed-in DocumentNodes
for too long.
#11370 25e2cb4
Thanks @phryneas! - parse
function: improve memory management
WeakCache
instead of Map
to keep a limited number of parsed resultsparse.resetCache()
method#11389 139acd1
Thanks @phryneas! - documentTransform
: use optimism
and WeakCache
instead of directly storing data on the Trie
#11358 7d939f8
Thanks @phryneas! - Fixes a potential memory leak in Concast
that might have been triggered when Concast
was used outside of Apollo Client.
#11344 bd26676
Thanks @phryneas! - Add a resetCache
method to DocumentTransform
and hook InMemoryCache.addTypenameTransform
up to InMemoryCache.gc
#11367 30d17bf
Thanks @phryneas! - print
: use WeakCache
instead of WeakMap
#11387 4dce867
Thanks @phryneas! - QueryManager.transformCache
: use WeakCache
instead of WeakMap
#11369 2a47164
Thanks @phryneas! - Persisted Query Link: improve memory management
WeakCache
instead of WeakMap
to keep a limited number of hash resultspersistedLink.resetHashCache()
method#10804 221dd99
Thanks @phryneas! - use WeakMap in React Native with Hermes
#11355 7d8e184
Thanks @phryneas! - InMemoryCache.gc now also triggers FragmentRegistry.resetCaches (if there is a FragmentRegistry)
#11409 2e7203b
Thanks @phryneas! - Adds an experimental ApolloClient.getMemoryInternals
helper
#11343 776631d
Thanks @phryneas! - Add reset
method to print
, hook up to InMemoryCache.gc
useLoadableQuery
#11300 a815873
Thanks @jerelmiller! - Introduces a new useLoadableQuery
hook. This hook works similarly to useBackgroundQuery
in that it returns a queryRef
that can be used to suspend a component via the useReadQuery
hook. It provides a more ergonomic way to load the query during a user interaction (for example when wanting to preload some data) that would otherwise be clunky with useBackgroundQuery
.
function App() {
const [loadQuery, queryRef, { refetch, fetchMore, reset }] =
useLoadableQuery(query, options);
return (
<>
<button onClick={() => loadQuery(variables)}>Load query</button>
<Suspense fallback={<SuspenseFallback />}>
{queryRef && <Child queryRef={queryRef} />}
</Suspense>
</>
);
}
function Child({ queryRef }) {
const { data } = useReadQuery(queryRef);
// ...
}
createQueryPreloader
#11412 58db5c3
Thanks @jerelmiller! - Add the ability to start preloading a query outside React to begin fetching as early as possible. Call createQueryPreloader
to create a preloadQuery
function which can be called to start fetching a query. This returns a queryRef
which is passed to useReadQuery
and suspended until the query is done fetching.
const preloadQuery = createQueryPreloader(client);
const queryRef = preloadQuery(QUERY, { variables, ...otherOptions });
function App() {
return {
<Suspense fallback={<div>Loading</div>}>
<MyQuery />
</Suspense>
}
}
function MyQuery() {
const { data } = useReadQuery(queryRef);
// do something with data
}
#11178 4d64a6f
Thanks @sebakerckhof! - Support re-using of mocks in the MockedProvider
#6701 8d2b4e1
Thanks @prowe! - Ability to dynamically match mocks
Adds support for a new property MockedResponse.variableMatcher
: a predicate function that accepts a variables
param. If true
, the variables
will be passed into the ResultFunction
to help dynamically build a response.
useQueryRefHandlers
hook#11412 58db5c3
Thanks @jerelmiller! - Create a new useQueryRefHandlers
hook that returns refetch
and fetchMore
functions for a given queryRef
. This is useful to get access to handlers for a queryRef
that was created by createQueryPreloader
or when the handlers for a queryRef
produced by a different component are inaccessible.
const MyComponent({ queryRef }) {
const { refetch, fetchMore } = useQueryRefHandlers(queryRef);
// ...
}
optimisticResponse
updates with the IGNORE
sentinel object#11410 07fcf6a
Thanks @sf-twingate! - Allow returning IGNORE
sentinel object from optimisticResponse
functions to bail-out from the optimistic update.
Consider this example:
const UPDATE_COMMENT = gql`
mutation UpdateComment($commentId: ID!, $commentContent: String!) {
updateComment(commentId: $commentId, content: $commentContent) {
id
__typename
content
}
}
`;
function CommentPageWithData() {
const [mutate] = useMutation(UPDATE_COMMENT);
return (
<Comment
updateComment={({ commentId, commentContent }) =>
mutate({
variables: { commentId, commentContent },
optimisticResponse: (vars, { IGNORE }) => {
if (commentContent === "foo") {
// conditionally bail out of optimistic updates
return IGNORE;
}
return {
updateComment: {
id: commentId,
__typename: "Comment",
content: commentContent,
},
};
},
})
}
/>
);
}
The IGNORE
sentinel can be destructured from the second parameter in the callback function signature passed to optimisticResponse
.
#11301 46ab032
Thanks @alessbell! - Add multipart subscription network adapters for Relay and urql
import { createFetchMultipartSubscription } from "@apollo/client/utilities/subscriptions/relay";
import { Environment, Network, RecordSource, Store } from "relay-runtime";
const fetchMultipartSubs = createFetchMultipartSubscription(
"http://localhost:4000"
);
const network = Network.create(fetchQuery, fetchMultipartSubs);
export const RelayEnvironment = new Environment({
network,
store: new Store(new RecordSource()),
});
import { createFetchMultipartSubscription } from "@apollo/client/utilities/subscriptions/urql";
import { Client, fetchExchange, subscriptionExchange } from "@urql/core";
const url = "http://localhost:4000";
const multipartSubscriptionForwarder = createFetchMultipartSubscription(url);
const client = new Client({
url,
exchanges: [
fetchExchange,
subscriptionExchange({
forwardSubscription: multipartSubscriptionForwarder,
}),
],
});
skipPollAttempt
callback function#11397 3f7eecb
Thanks @aditya-kumawat! - Adds a new skipPollAttempt
callback function that's called whenever a refetch attempt occurs while polling. If the function returns true
, the refetch is skipped and not reattempted until the next poll interval. This will solve the frequent use-case of disabling polling when the window is inactive.
useQuery(QUERY, {
pollInterval: 1000,
skipPollAttempt: () => document.hidden, // or !document.hasFocus()
});
// or define it globally
new ApolloClient({
defaultOptions: {
watchQuery: {
skipPollAttempt: () => document.hidden, // or !document.hasFocus()
},
},
});
FAQs
A fully-featured caching GraphQL client.
The npm package @apollo/client receives a total of 2,002,841 weekly downloads. As such, @apollo/client popularity was classified as popular.
We found that @apollo/client demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Ensure open-source compliance with Socket’s License Enforcement Beta. Set up your License Policy and secure your software!
Product
We're launching a new set of license analysis and compliance features for analyzing, managing, and complying with licenses across a range of supported languages and ecosystems.
Product
We're excited to introduce Socket Optimize, a powerful CLI command to secure open source dependencies with tested, optimized package overrides.