VOOZH about

URL: https://blog.logrocket.com/data-retrieval-in-graphql-with-react-apollo/

⇱ Data retrieval in GraphQL with react-apollo - LogRocket Blog


2020-12-25
1322
#apollo#graphql#react
Belinda Ijeoma
31091
πŸ‘ Image

See how LogRocket's Galileo AI surfaces the most severe issues for you

No signup required

Check it out

In this article, we will explore how to use the GraphQL query language with Apollo Client to efficiently and seamlessly fetch data from a server. By the end of your reading, you will learn how to use and install GraphQL and Apollo client, and two different approaches for how to perform query and mutation operations within react-apollo.

πŸ‘ Data retrieval in GraphQL with React Apollo

πŸš€ Sign up for The Replay newsletter

The Replay is a weekly newsletter for dev and engineering leaders.

Delivered once a week, it's your curated guide to the most important conversations around frontend dev, emerging AI tools, and the state of modern software.

GraphQL

GraphQL is a query language that uses a defined system to describe how a user should ask for data from an API. GraphQL requires that a user specify the exact data that needs to be transferred β€” most often from the server β€” which will then be loaded to the client side.

Before we learn about how specific query operations can be performed with Apollo, we will review some of the basic actions and operations that can be performed within the GraphQL query library.

1. Query

A GraphQL query operation is concerned with basic data fetching from the server side.

 {
 query getItems {
 Items {
 id
 chair
 stool
 }
 }
 }

The above is a GraphQL query with name getItems, that fetches id, chair, and stool.

2. Mutation

Adding the mutation keyword performs basic CRUD (create, read, update and delete) operations in a GraphQL application.

{
 mutation addUser(name: String!, email: String!){
 addUser(name: $name, email: $email){
 id
 name
 email
 created_at
 }
 }
 }

The above addUser mutation returns a user’s name, id, email, and create_at fields when the user’s name and email is specified.

3. Subscription

This is an event-based action that involves data transfer from the server to the client side when a particular event is executed. To create a subscription in GraphQL, we need to add the subscription type to our schema:

const typeDefs = gql`
 type Subscription {
 bookAdded: Book
 }`

The next step is to create a resolver. Pubsub is notified of an event in this case from within a mutation.

const BOOK_ADDED = 'BOOK_ADDED';

const resolvers = {
 Subscription: {
 bookAdded: {
 subscribe: () => pubsub.asyncIterator([BOOK_ADDED]),
 },
 },

 Mutation: {
 addBook(root, args, context) {
 pubsub.publish(BOOK_ADDED, { bookAdded: args });
 return postController.addBook(args);
 },
 },
};

The subscription is triggered by a publish call inside the mutation.

Apollo

Apollo serves as a state management library for local and remote data storage in a GraphQL application. Some of the basic operations that you can perform with the help of Apollo include: fetching, local state storage, and caching. The Apollo client also has a built-in integration with React that makes development much easier.

Some basic features of Apollo client include:

Declarative data fetching

Apollo client allows a user to specify the exact data needed from an application programming interface. React uses a useQuery Hook that enables us perform data retrieving and data fetching operations in a GraphQL application. An example from the official documentation can be found below:

function Feed() {
 const { loading, error, data } = useQuery(GET_DOGS);
 if (error) return <Error />;
 if (loading || !data) return <Fetching />;

 return <DogList dogs={data.dogs} />;
 }

With the help of the useQuery Hook, we are able to fetch data from the GraphQL server that will lead to a UI update to reflect any changes.

Caching

Aside from the main fetching operations that can be performed with GraphQL, intelligent data caching operations can also be performed with with little to no configuration.

Below is an Apollo client configuration for data caching:

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

const client = new ApolloClient({
 cache: new InMemoryCache()
});

Other benefits that come with Apollo client include:

  1. Support for modern React Hooks
  2. Compatibility
  3. Strong community support
  4. Pagination

Installation and use of GraphQL and Apollo Client

If you have not set up your React application, start by running the following:

npx create-react-app

To make use of GraphQL and Apollo in your React application, you will need to install the following dependencies:

npm install apollo-boost graphql react-apollo

Your React application with GraphQL is now set up and ready for use!

To create a connection, first create an index.js file and add the following snippet:

import ApolloClient from "apollo-boost";
import { ApolloProvider } from 'react-apollo';

const client = new ApolloClient({
 uri: //graghql server url should be here
 });

Next, wrap your app component with the ApolloProvider, passing the client as props:

ReactDOM.render(
 <ApolloProvider client={client}>
 <App />
 </ApolloProvider>,
 document.getElementById("root")
 );

At the beginning, we talked about basic operations that you can perform with GraphQL including query and mutation. Now let’s, look at how to perform some of these operations with Apollo using the useQuery Hook approach and the render props approach.

Queries

GraphQL queries involve reading and fetching of data. We can take two approaches in performing this operation with React Apollo: the useQuery Hook approach and the render props approach.

useQuery Hook approach

First, let’s create a GraphQL query and name it getItems as shown below:

import React from "react";
import { useQuery } from "react-apollo";
import { gql } from "apollo-boost";

const GET_ITEMS = gql`
 query GetItems {
 items {
 id
 oneitem
 }
 }
`;

Next, create a functional component and pass the GraphQL query to the useQuery Hook as follows:

function DisplayItems() {
 const { loading, error, data } = useQuery(GET_ITEMS);

 if (loading) return 'Loading...';
 if (error) return `Error! ${error.message}`;

 return (
 <select name="items">
 {data.items.map(item => (
 <option key={item.id} value={item.oneitem}>
 {item.oneitem}
 </option>
 ))}
 </select>
 );
}

The application will update when the new data is fetched or when an error occurs to reflect the new changes.


Over 200k developers use LogRocket to create better digital experiences

πŸ‘ Image
Learn more β†’

Render props approach

For the render props approach, the first step remains the same except for an additional importation of query from react-apollo that we previously installed:

import React from "react";
import { Query } from "react-apollo";
import { gql } from "apollo-boost";

const GET_ITEMS = gql`
 query GetItems {
 items {
 id
 oneitem
 }
 }
`;

Next, we will make use of query by passing the created GraphQL query to it and using it as follows:



function DisplayItems() {

 if (loading) return 'Loading...';
 if (error) return `Error! ${error.message}`;

 return (
 <Query query={GET_ITEMS}>
 <select name="items">
 {data.items.map(item => (
 <option key={item.id} value={item.oneitem}>
 {item.oneitem}
 </option>
 ))}
 </select>
 </Query>
 );
}

Just like in the hooks approach, the application will either update to reflect the new data or return an error.

Mutation

Mutation involves performing creating, updating, and deleting operations. As is the case with queries, we can make use of the hooks approach and render props approach when dealing with mutation.

Hooks approach

First let’s import the dependencies including useMutation imported from react-apollo.

import React, { useState } from 'react';
import { useMutation } from 'react-apollo';
import { gql } from 'apollo-boost';

const ADD_TODO = gql`
 mutation AddTodo($type: String!) {
 addTodo(type: $type) {
 id
 type
 }
 }
`;

Next is to create a functional component named AddToDo and pass our ADD_TODO mutation to the useMutation Hook:

function AddTodo() {
 let input;
 const [addTodo, { data }] = useMutation(ADD_TODO);

 return (
 <div>
 <form
 onSubmit={e => {
 e.preventDefault();
 addTodo({ variables: { type: input.value } });
 input.value = '';
 }}
 >
 <input
 ref={node => {
 input = node;
 }}
 />
 <button type="submit">Add Todo</button>
 </form>
 </div>
 );
}

Render props approach

Similar to the hooks approach, we need to import the necessary dependencies with a new mutation importation from react-apollo:

import React, { useState } from 'react';
import { useMutation } from 'react-apollo';
import { gql } from 'apollo-boost';

const ADD_TODO = gql`
 mutation AddTodo($type: String!) {
 addTodo(type: $type) {
 id
 type
 }
 }
`;

To complete, pass the created mutation as follows:

function AddTodo() {
 let input;

 return (
 <Mutation mutation={ADD_TODO}>
 <div>
 <form
 onSubmit={e => {
 e.preventDefault();
 addTodo({ variables: { type: input.value } });
 input.value = '';
 }}
 >
 <input
 ref={node => {
 input = node;
 }}
 />
 <button type="submit">Add Todo</button>
 </form>
 </div>
 </Mutation>
 );
}

Conclusion

GraphQL is a great choice when dealing with data fetching as it solves the over-fetching and under-fetching problems that come with RESTful APIs. Apollo Client makes GraphQL connection to a server easy, seamless, and efficient.

Get set up with LogRocket's modern React error tracking in minutes:

  1. Visit https://logrocket.com/signup/ to get an app ID
  2. Install LogRocket via npm or script tag. LogRocket.init() must be called client-side, not server-side

    $ npm i --save logrocket 
    
    // Code:
    
    import LogRocket from 'logrocket'; 
    LogRocket.init('app/id');
     
    // Add to your HTML:
    
    <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
    <script>window.LogRocket && window.LogRocket.init('app/id');</script>
     
  3. (Optional) Install plugins for deeper integrations with your stack:
    • Redux middleware
    • NgRx middleware
    • Vuex plugin
Get started now
πŸ‘ Image
πŸ‘ Image
πŸ‘ Image

Stop guessing about your digital experience with LogRocket

Get started for free

Recent posts:

Debug Next.js apps with AI agents and next-browser

Learn how next-browser gives AI agents runtime context for debugging Next.js apps, including React props, hydration, PPR, forms, and performance.

πŸ‘ Image
Emmanuel John
Jun 17, 2026 β‹… 9 min read

Stop hardcoding LLM SDKs: Dynamic LLM routing with OpenRouter and Next.js

Build dynamic LLM routing in Next.js with OpenRouter, TanStack AI, task classification, model fallbacks, and cost-aware routing.

πŸ‘ Image
Chizaram Ken
Jun 16, 2026 β‹… 13 min read

What is TSRX?: What JSX would look like if it were designed today

TSRX adds first-class control flow, conditional hooks, and scoped styles to React via a TypeScript compiler extension β€” no new framework required.

πŸ‘ Image
Ikeh Akinyemi
Jun 12, 2026 β‹… 6 min read

How to add authentication to a React Native app with Better Auth

Learn how to build a full React Native auth system using Better Auth and Expo β€” with email/password login, Google OAuth, session persistence, and protected routes.

πŸ‘ Image
Chinwike Maduabuchi
Jun 9, 2026 β‹… 13 min read
View all posts

Hey there, want to help make our blog better?

Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.

Sign up now