Article image React and GraphQL: Fetching Data

52. React and GraphQL: Fetching Data

Page 96 | Listen in audio

When building modern web applications, data fetching is a critical aspect that developers must address efficiently. Traditional REST APIs have been the go-to solution for many years, but GraphQL has emerged as a powerful alternative that offers more flexibility and efficiency. In this section, we will explore how React and GraphQL can be combined to fetch data effectively, providing a seamless experience for both developers and users.

GraphQL is a query language for APIs and a server-side runtime for executing queries by using a type system that you define for your data. Unlike REST, which requires multiple endpoints for different data requirements, GraphQL allows clients to request exactly the data they need, all in a single query. This reduces the number of requests and the amount of data transferred, which can significantly improve application performance.

To integrate GraphQL with a React application, we typically use Apollo Client, a popular library that provides a comprehensive set of features for interacting with GraphQL APIs. Apollo Client makes it easy to fetch, cache, and update application data, and it integrates seamlessly with React's component-based architecture.

Let's start by setting up Apollo Client in a React application. First, we need to install the necessary packages:

npm install @apollo/client graphql

Once the packages are installed, we can configure Apollo Client. We need to create an instance of ApolloClient and provide it with a URI pointing to our GraphQL server. We also need to set up an InMemoryCache to cache query results locally:

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

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

function App() {
  return (
    <ApolloProvider client={client}>
      <MyComponent />
    </ApolloProvider>
  );
}

With ApolloProvider, we wrap our React application to provide the Apollo Client instance to the entire component tree. This setup allows us to use the useQuery hook provided by Apollo Client to fetch data in our components.

Suppose we have a GraphQL server that provides information about books, and we want to fetch a list of books along with their titles and authors. We can define a GraphQL query and use the useQuery hook to execute it:

import { useQuery, gql } from '@apollo/client';

const GET_BOOKS = gql`
  query GetBooks {
    books {
      id
      title
      author
    }
  }
`;

function MyComponent() {
  const { loading, error, data } = useQuery(GET_BOOKS);

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

  return (
    <ul>
      {data.books.map((book) => (
        <li key={book.id}>
          {book.title} by {book.author}
        </li>
      ))}
    </ul>
  );
}

In the above example, we define a GraphQL query named GET_BOOKS using the gql template literal. This query requests the id, title, and author fields for each book. The useQuery hook is then used to execute this query. It returns an object with loading, error, and data properties, which we use to handle different states of the query.

When the query is loading, we display a loading message. If there's an error, we display an error message. Once the data is successfully fetched, we map over the list of books and render each book's title and author in a list.

One of the powerful features of GraphQL is its ability to fetch related data in a single query. For example, if our book data also includes information about reviews, we can extend our query to fetch reviews along with the books:

const GET_BOOKS_WITH_REVIEWS = gql`
  query GetBooksWithReviews {
    books {
      id
      title
      author
      reviews {
        rating
        comment
      }
    }
  }
`;

function MyComponent() {
  const { loading, error, data } = useQuery(GET_BOOKS_WITH_REVIEWS);

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

  return (
    <ul>
      {data.books.map((book) => (
        <li key={book.id}>
          {book.title} by {book.author}
          <ul>
            {book.reviews.map((review, index) => (
              <li key={index}>
                {review.rating} stars - {review.comment}
              </li>
            ))}
          </ul>
        </li>
      ))}
    </ul>
  );
}

In this example, we extend the query to include the reviews field, which contains an array of review objects with rating and comment fields. This allows us to fetch and display both books and their reviews in a single request, showcasing the efficiency of GraphQL.

GraphQL also supports variables, which enable us to make dynamic queries based on user input or other application state. For instance, if we want to fetch books by a specific author, we can define a query with a variable:

const GET_BOOKS_BY_AUTHOR = gql`
  query GetBooksByAuthor($author: String!) {
    books(author: $author) {
      id
      title
    }
  }
`;

function BooksByAuthor({ author }) {
  const { loading, error, data } = useQuery(GET_BOOKS_BY_AUTHOR, {
    variables: { author },
  });

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

  return (
    <ul>
      {data.books.map((book) => (
        <li key={book.id}>{book.title}</li>
      ))}
    </ul>
  );
}

In this code, we define a query GET_BOOKS_BY_AUTHOR that takes a variable $author. The useQuery hook is called with an additional variables option, allowing us to pass the variable value dynamically. This makes our component flexible and reusable for different authors.

As you can see, React and GraphQL together provide a robust solution for data fetching in modern web applications. GraphQL's ability to request specific data, its support for nested queries, and its use of variables make it a highly efficient and flexible choice. When combined with Apollo Client, developers can easily manage data fetching, caching, and updates, ensuring a smooth and responsive user experience.

In summary, integrating GraphQL with React enhances the way we handle data in applications. It reduces over-fetching and under-fetching of data, simplifies the client-side code, and provides a more intuitive way to work with APIs. As you continue to develop your skills in React, exploring GraphQL will open up new possibilities for building efficient and scalable applications.

Now answer the exercise about the content:

What is one of the main advantages of using GraphQL over traditional REST APIs when fetching data in modern web applications?

You are right! Congratulations, now go to the next page

You missed! Try again.

Article image Integrating REST APIs with React Components

Next page of the Free Ebook:

97Integrating REST APIs with React Components

8 minutes

Earn your Certificate for this Course for Free! by downloading the Cursa app and reading the ebook there. Available on Google Play or App Store!

Get it on Google Play Get it on App Store

+ 6.5 million
students

Free and Valid
Certificate with QR Code

48 thousand free
exercises

4.8/5 rating in
app stores

Free courses in
video, audio and text