ABC of GraphQL In A React App
The Apollo GraphQL client is easily one of the very popular way to interface with GraphQL API on the client-side. In this article i will show you how to setup Apollo in a React app using Apollo Boost and React Apollo 2.1+.
Why do we need these two?
- Apollo Boost: The setup for Apollo on the client in the past requires a lot of boilerplate code but Apollo Boost solves it. The bundling of apollo-client, apollo-cache-inmemory, apollo-link-error, apollo-link-http and apollo-link-state allows for an easier setup.
- React Apollo: A React-specific integration for Apollo. It provides us with tons of feature like the Query and Mutation components.
So without further ado lets play!
Installation
First, we initialize a React project using npx and Create React App:
$ npx create-react-app hello-graphql
Next cd into the project and start a local dev server:
$ cd hello-graphql && yarn start
Moving on, a few extra packages will be added in our project, namely: graphql, graphql-tag, apollo-boost and react-apollo. Add them using npm or Yarn:
$ yarn add graphql graphql-tag apollo-boost react-apollo
# or, using npm:
$ npm i graphql graphql-tag apollo-boost react-apollo
Congratulations if you successfully added the packages, we can now setup the Apollo client.
Setup
We’ll begin a client and give it the URI to our GraphQL server endpoint and use the ApolloProvider component to render the client available in our app components.
In this scenario our endpoint will point to an existing Apollo Launchpad instance with data about Star Wars:
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { ApolloProvider } from 'react-apollo';
import { ApolloClient, HttpLink, InMemoryCache } from 'apollo-boost';
import './index.css';
import App from './App';
const client = new ApolloClient({
link: new HttpLink({ uri: 'https://mpjk0plp9.lp.gql.zone/graphql' }),
cache: new InMemoryCache()
});
const AppWithProvider = () => (
<ApolloProvider client={client}>
<App />
</ApolloProvider>
);
ReactDOM.render(<AppWithProvider />, document.getElementById('root'));
A few things to note:
- We begin the client with an HttpLink which points to our GraphQL endpoint and then also state Apollo’s InMemoryCache as our caching utility.
- We use the ApolloProvider component, pass it at our client as prop and then wrap it around our App component.
Query Component Example
With everything’s in place, we can start running queries against the GraphQL endpoint. For this, we’ll use React Apollo’s Query component, which makes use of the render prop pattern to return data back from the query.
Here’s an example where we query for a Star Wars’ episode hero and his/her friends:
App.js
import React from 'react';
import PropTypes from 'prop-types';
import { Query } from 'react-apollo';
import gql from 'graphql-tag';
const QUERY = gql`
query HeroFriends($episode: Episode!) {
hero(episode: $episode) {
name
friends {
name
}
}
}
`;
const HeroAndFriends = ({ episode }) => (
<Query query={QUERY} variables={{ episode }}>
{({ data, error, loading }) => {
if (error) return '💩 Oops!';
if (loading) return 'Patience na dem dey rush us...';
return (
<React.Fragment>
<h1>Hero: {data.hero.name}</h1>
<h2>His/her friends:</h2>
<ul>
{data.hero.friends.map(friend => (
<li key={friend.name}>{friend.name}</li>
))}
</ul>
</React.Fragment>
);
}}
</Query>
);
HeroAndFriends.propTypes = { episode: PropTypes.string };
HeroAndFriends.defaultProps = { episode: 'NEWHOPE' };
const App = () => <HeroAndFriends episode="EMPIRE" />;
export default App;
And let’s breakdown the important things happening in the code:
- React Apollo’s Query component takes a required query prop with a GraphQL query having parsed using graphql-tag’s gql. Query also takes a required children prop that should be a function. Here we also passed-in a variable prop to provide a variable value to our query.
- Query can also take a number of optional props like pollInterval, fetchPolicy, errorPolicy and delay, among others.
- The function passed to the children prop receives an object with some useful properties. Here we’re making use of data, error and loading, but other properties like networkStatus, refetch and fetchMore are also available.
- The data property stores the data returned back from the query, the error property holds an error object, if any, and the loading property will be true while the query is in-flight.
You can also dive a little bit deeper by having a look at the official docs.
Running queries using React and GraphQL couldn’t be easier. In my next post we'll explore the Mutation component and also run GraphQL mutations. ⚛️ There you have it!
Brilliantly written.