DEV Community

Radu Alex
Radu Alex

Posted on

React.Js, GraphQL and Apollo client

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:

npm install @apollo/client
Enter fullscreen mode Exit fullscreen mode

or

yarn add @apollo/client
Enter fullscreen mode Exit fullscreen mode

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:

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;
Enter fullscreen mode Exit fullscreen mode

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:

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;
Enter fullscreen mode Exit fullscreen mode

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:

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;
Enter fullscreen mode Exit fullscreen mode

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.

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;
Enter fullscreen mode Exit fullscreen mode

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:

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,
});
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)