React.Js, GraphQL and Apollo client
Tags: react, graphql, apollo, javascript
Published: 2023-02-22 20:49:04

GraphQL has quickly become a popular alternative to traditional RESTful APIs due to its ability to handle complex queries and its more efficient data fetching capabilities. ReactJS, on the other hand, has emerged as a leading frontend library for building fast and responsive web applications. Connecting GraphQL to ReactJS is therefore a highly sought-after skill for developers.

One of the most popular libraries for integrating GraphQL with ReactJS is Apollo Client. Apollo Client is a powerful GraphQL client that makes it easy to query your GraphQL API and integrate the data into your React components. In this blog post, we will explore how to connect GraphQL to ReactJS with Apollo Client.

## Prerequisites
To follow along with this tutorial, you should have a basic understanding of ReactJS and GraphQL. You will also need to have a GraphQL API set up, whether that is using a third-party service or creating your own.

## Step 1: Installing Apollo Client

To get started, we need to install Apollo Client. You can install it using npm or yarn:

```js
npm install @apollo/client
```
or

```js
yarn add @apollo/client
```

## Step 2: Setting up an Apollo Provider

The first thing we need to do to use Apollo Client in our React application is to set up an Apollo Provider. The Apollo Provider is a React component that wraps your application and provides the Apollo Client instance to your components. To set up an Apollo Provider, create a new file called **ApolloProvider.js** and add the following code:

```js
import { ApolloClient, InMemoryCache } from '@apollo/client';
import { ApolloProvider } from '@apollo/client/react';

const client = new ApolloClient({
  uri: 'https://mygraphqlapi.com/graphql',
  cache: new InMemoryCache(),
});

const Apollo = ({ children }) => (
  <ApolloProvider client={client}>
    {children}
  </ApolloProvider>
);

export default Apollo;
```

In the example above, we create a new ApolloClient instance with the URI of our GraphQL API and an `InMemoryCache` instance as the cache. We then wrap our React application with the `ApolloProvider` component and pass in the Apollo Client instance as the client prop. The `ApolloProvider` component makes the Apollo Client instance available to all of the components in our application.

## Step 3: Querying data with Apollo Client

Now that we have set up an Apollo Provider, we can use Apollo Client to query data from our GraphQL API. To do this, we can create a new React component called **Posts.js**:
```js
import { useQuery, gql } from '@apollo/client';

const POSTS_QUERY = gql`
  query Posts {
    posts {
      title
      body
      author {
        name
      }
    }
  }
`;

const Posts = () => {
  const { loading, error, data } = useQuery(POSTS_QUERY);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  return (
    <div>
      {data.posts.map(post => (
        <div key={post.id}>
          <h1>{post.title}</h1>
          <p>{post.body}</p>
          <p>Author: {post.author.name}</p>
        </div>
      ))}
    </div>
  );
};

export default Posts;
```


In the example above, we use the `useQuery` hook provided by Apollo Client to query data from our GraphQL API. We define our query using the `gql` tag and pass it to the `useQuery` hook. The `useQuery` hook returns an object with `loading`, `error`, and `data` properties. If the query is still loading, we display a loading message, and if there is an error, we display an error message. If the data has been fetched successfully, we can then display it in our component. In this example, we display a list of posts with their titles, bodies, and author names.

## Step 4: Adding mutations with Apollo Client
In addition to querying data, we can also use Apollo Client to perform mutations on our GraphQL API. Mutations allow us to modify data on the server, such as creating, updating, or deleting records. To add a mutation to our application, we can create a new React component called **AddPost.js**:

```js
import { useMutation, gql } from '@apollo/client';

const ADD_POST_MUTATION = gql`
  mutation AddPost($title: String!, $body: String!, $author: String!) {
    addPost(title: $title, body: $body, author: $author) {
      id
      title
      body
      author {
        name
      }
    }
  }
`;

const AddPost = () => {
  let inputTitle, inputBody, inputAuthor;
  const [addPost, { data }] = useMutation(ADD_POST_MUTATION);

  const handleSubmit = e => {
    e.preventDefault();
    addPost({
      variables: {
        title: inputTitle.value,
        body: inputBody.value,
        author: inputAuthor.value,
      },
    });
    inputTitle.value = '';
    inputBody.value = '';
    inputAuthor.value = '';
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <label>
          Title:
          <input type="text" ref={node => (inputTitle = node)} />
        </label>
        <label>
          Body:
          <input type="text" ref={node => (inputBody = node)} />
        </label>
        <label>
          Author:
          <input type="text" ref={node => (inputAuthor = node)} />
        </label>
        <button type="submit">Add Post</button>
      </form>
      {data && (
        <p>
          Post added: {data.addPost.title} by {data.addPost.author.name}
        </p>
      )}
    </div>
  );
};

export default AddPost;
```

In the example above, we define a mutation using the `gql` tag, passing in the variables we want to add to our GraphQL API. We use the `useMutation` hook to execute the mutation, and then we define a `handleSubmit` function that gets called when the form is submitted. The `handleSubmit` function calls the `addPost` mutation, passing in the variables from the form. We then reset the form fields.

If the mutation is successful, the `data` object will contain the result of the mutation, which we can display in our component. In this example, we display a message indicating that the post has been added, along with the title and author name.

## Step 5: Using Apollo Client in our application
Now that we have defined our components for querying and mutating data, we can use them in our application. To do this, we need to import our `ApolloProvider` and wrap our application with it. We can then use our `Posts` and `AddPost` components anywhere in our application.

```js
import React from 'react';
import Apollo from './ApolloProvider';
import Posts from './Posts';
import AddPost from './AddPost';

const App = () => (
  <Apollo>
    <div>
      <Posts />
      <AddPost />
    </div>
  </Apollo>
);

export default App;
```

In the example above, we import our `ApolloProvider` component from the `@apollo/client` library and wrap our `Posts` and `AddPost` components inside it. This makes the `ApolloProvider` available to all of our components, allowing them to use Apollo Client to query and mutate data.

## Step 6: Configuring the Apollo Client cache

By default, Apollo Client uses an in-memory cache to store data that has been fetched from the server. This cache allows Apollo Client to avoid making unnecessary network requests when data has already been fetched.

In some cases, we may want to configure the cache behaviour. For example, we may want to specify how long data should be cached, or we may want to exclude certain fields from being cached. To do this, we can create a new instance of `InMemoryCache` and pass it to our `ApolloClient` constructor:

```js
import { ApolloClient, InMemoryCache } from '@apollo/client';

const cache = new InMemoryCache({
  typePolicies: {
    Post: {
      fields: {
        body: {
          // don't cache the body field
          merge: false,
        },
      },
    },
  },
});

const client = new ApolloClient({
  uri: 'https://mygraphqlapi.com/graphql',
  cache,
});
```

In the example above, we create a new instance of `InMemoryCache` and pass it to our `ApolloClient` constructor. We also define a `typePolicies` object, which allows us to specify how certain types should be cached. In this example, we specify that the `body` field of the `Post` type should not be cached.

## Conclusion
In this blog post, we have learned how to connect GraphQL to React using Apollo Client. We started by creating an instance of `ApolloClient` and defining a query to fetch data from our GraphQL API. We then used the `useQuery` hook to execute the query and display the data in our React component. We also learned how to use the `useMutation` hook to perform mutations on our GraphQL API.

Finally, we learned how to configure the Apollo Client cache to control how data is cached and retrieved from the server. With Apollo Client, we can easily build powerful and efficient React applications that interact with GraphQL APIs.