GraphQL API Integration with React based Project
In order for us to fetch data from a GraphQL API in React, we need to install Apollo Client. Apollo Client gives us a way to connect to our GraphQL data source and lets us execute GraphQL operations. Apollo Client also manages state and allows us cache our data on the client-side.
Installation
First, let's install the packages we need:
npm install @apollo/client graphql
@apollo/client
: This single package contains virtually everything you need to set up Apollo Client. It includes the in-memory cache, local state management, error handling, and a React-based view layer.graphql
: This package provides logic for parsing GraphQL queries.
Create a client
Now that we have all the dependencies we need, let's initialize an ApolloClient
instance. You'll need to provide it the URL of a running GraphQL server, such as this CodeSandbox instance.
In index.js
, let's import ApolloClient
from @apollo/client
and provide our GraphQL server's URL as the uri
property of the constructor's configuration object:
Always remember to replace API_SECRET
with the correct value that you copied from apito console.
Go to this page if you do not know where to find your api secrets for your project
import { ApolloClient, InMemoryCache } from '@apollo/client';
const client = new ApolloClient({
uri: 'https://api.apito.io/secured/graphql',
cache: new InMemoryCache(),
headers: {
Authorization: `Bearer API_SECRET`,
},
});
That's it! Our client
is ready to start fetching data. Now, before we start using Apollo Client with React, let's first try sending a query with plain JavaScript.
In the same index.js
file, call client.query()
with the query string shown below. You'll need to import the gql
function to parse the query string into a query document.
import { gql } from '@apollo/client';
// const client = ...
client
.query({
query: gql`
query GetRates {
rates(currency: "USD") {
currency
}
}
`
})
.then(result => console.log(result));
Run this code, open your console, and inspect the result object. You should see a data
property with rates
attached, along with some other properties like loading
and networkStatus
.
Although executing GraphQL operations like this can be useful, Apollo Client really shines when it's integrated with a view layer like React. You can bind queries to your UI and update it automatically as new data is fetched.
Let's look at how that works!
Connect your client to React
You connect Apollo Client to React with the ApolloProvider
component. The ApolloProvider
is similar to React's Context.Provider
. It wraps your React app and places the client on the context, which enables you to access it from anywhere in your component tree.
In index.js
, let's wrap our React app with an ApolloProvider
. We suggest putting the ApolloProvider
somewhere high in your app, above any component that might need to access GraphQL data. For example, it could be outside of your root route component if you're using React Router.
import React from 'react';
import { render } from 'react-dom';
import { ApolloProvider } from '@apollo/client';
function App() {
return (
<ApolloProvider client={client}>
<div>
<h2>My first Apollo app 🚀</h2>
</div>
</ApolloProvider>
);
}
render(<App />, document.getElementById('root'));
Request data
Once your ApolloProvider
is hooked up, you're ready to start requesting data with useQuery
. useQuery
is a React hook that use the Hooks API to share GraphQL data with your UI.
First, pass your GraphQL query (wrapped in the gql
function) to the useQuery
hook. When your component renders and the useQuery
hook runs, a result object is returned that contains loading
, error
, and data
properties:
- Apollo Client tracks error and loading state for you, which are reflected in the
loading
anderror
properties. - When the result of your query comes back, it's attached to the
data
property.
Let's create an ExchangeRates
component in index.js
to see the useQuery
hook in action:
import { useQuery, gql } from '@apollo/client';
const EXCHANGE_RATES = gql`
query GetExchangeRates {
rates(currency: "USD") {
currency
rate
}
}
`;
function ExchangeRates() {
const { loading, error, data } = useQuery(EXCHANGE_RATES);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
return data.rates.map(({ currency, rate }) => (
<div key={currency}>
<p>
{currency}: {rate}
</p>
</div>
));
}
Congrats, you just made your first useQuery
-based component! 🎉 If you render your ExchangeRates
component within your App
component from the previous example, you'll first see a loading indicator on the page, followed by data when it's ready. Apollo Client automatically caches this data when it comes back from the server, so you won't see a loading indicator if you run the same query again.
To play around with the app we just built, check it out on CodeSandbox. But don't stop there! Try building more components that use useQuery
, and experiment with the concepts you just learned.
Detailed Guide
For an in depth and detailed guide, be sure to check out the official apollo guide here