How to Integrate GraphQL with React?
Thursday, June 12, 2025React, a popular JS library for building user interfaces, when integrated with a powerful API query language like GraphQL, the resultant application is a blend of the advanced features of both technologies. We’ll begin by understanding React and GraphQL, then explore the pros of their integration. Next, we will outline the integration method used by most React development companies with the use of Apollo Client to facilitate the integration, and review various GraphQL libraries available for React development.
1. What is GraphQL?
GraphQL is a Facebook-developed open-source data query language and runtime for APIs. It serves as an alternative to RESTAPI. With GraphQL, you can write a single query to fetch the precise data you require without writing multiple queries for multiple endpoints. This simplifies data aggregation from different sources. You can specify the shape and structure of the required data through declarative data fetching by leveraging the type system of GraphQL. This resolves the underfetching and overfetching problems of conventional APIs.
2. About React
React is a component-based frontend JavaScript library used to develop dynamic and responsive user interfaces. It is an open-source library created by Facebook. The user interface in React is divided into small reusable components forming the building blocks. You can reuse any component multiple times, thus improving productivity and reducing development costs. React uses the virtual DOM, preventing the complete update of the actual DOM if there are any changes in any of the components. This increases the speed of the application in loading content.
3. What are the Advantages of Integrating React with GraphQL?
Businesses are increasingly adopting the integration of GraphQL with React to enhance the usability of their React applications and provide a rich user experience. But do you know how the integration benefits web applications? Why is GraphQL taking over REST APIs? Let’s discuss the significant advantages of integrating GraphQL with React:
- Reduced Network Requests: A GraphQL query selectively retrieves only the necessary data from the server, decreasing the network requests made by the React application. This decreases the network overhead and enhances the application’s performance.
- Simplified Data Management: The strongly typed schema-based approach of GraphQL gives developers a proper method to interact with APIs, increasing their understanding of the data flow within a React application.
- No Data Overfetching or Underfetching: Using a GraphQL query, the client receives only the requested fields from the server over the network. The server extracts the required data from different sources and returns it to the client, increasing web application efficiency.
- Powerful Typing and Validation: The type system in GraphQL synchronizes the client and server by ensuring that both follow the same data schema. It serves as a built-in validation that detects any data-based issues and inconsistencies in advance and lessens the chances of runtime errors. This increases the reliability and stability of applications.
- Simplified State Management: Using the Apollo Client JavaScript library with GraphQL eliminates the need for complex React state management libraries like Redux in your applications. It manages both remote and local states in a GraphQL-based application. The React app can cache, fetch, and update data directly from your GraphQL API.
- Optimistic UI and Real-Time Updates: If your application demands real-time data, you can integrate GraphQL with React. GraphQL gives real-time updates through subscriptions, helping you to develop interactive applications such as chat apps and collaboration platforms.
- Ecosystem Support: GraphQL has an extensive ecosystem of plugins, libraries, documentation, and online support owing to a large community of developers.
4. How to Integrate GraphQL with React?
Here we will explore how to integrate GraphQL with React using Apollo Client.
4.1 Set Up Your React App
There are two ways to create a React app.
npm create-react-app my-react-app
npm create vite@latest my-react-app
Here, the second way is used, open the terminal and run the following command.
npm create vite@latest my-react-app --template react-ts
Here, the template react-ts means create a React app with TypeScript.
Once the project is created, run cd my-react-app to go root directory of the project and then run npm install to install the required libraries and dependencies.
You can use npm or yarn for package management.
4.2 Set Up the Apollo Client
Run the command below in the root directory using the terminal.
npm install @apollo/client
After the package is installed, let’s configure the Apollo Client and create an instance of it, which will be further used in React to interact with the GraphQL API.
// src/graphql/config.ts
import { ApolloClient, InMemoryCache } from '@apollo/client';
export const client = new ApolloClient({
uri: 'https://rickandmortyapi.com/graphql',
cache: new InMemoryCache(),
});
In the URL, you can replace your GraphQL URL. Here we have used a free online GraphQL API.
In the above code, we are configuring the ApolloClient class to fetch and send data to and from the GraphQL server through GraphQL queries and mutations. The ApolloClient class belongs to the Apollo Client library, which we’ll study in the upcoming section.
The GraphQL server deals with multiple requests at a time, creating a time lag between requests and responses. To reduce this, Apollo Client implements built-in caching mechanisms to improve performance. By default, Apollo Client uses the InMemoryCache strategy.
Now let’s warp the created instance to react to access GraphQL in React.
// src/main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./App.tsx";
import { client } from "./graphql/config.ts";
import { ApolloProvider } from "@apollo/client";
createRoot(document.getElementById("root")!).render(
);
ApolloProvider links the Apollo Client with your React application. You need to use the useQuery and useMutation hooks to allow any React component to access the GraphQL data.
4.3 Create a GraphQL Query to Get Data
// src/graphql/queries.ts
import { gql } from "@apollo/client";
export const GET_CHARACTERS = gql`
query Query {
characters(page: 2, filter: { name: "Morty" }) {
info {
count
}
results {
name
}
}
location(id: 1) {
id
}
episodesByIds(ids: [1, 2]) {
id
}
}
`;
GQL is a function from Apollo Client that is used to define GraphQL queries and mutations.
This is a GraphQL query named Query. It requests data from three different parts of the API: characters, location, and episodesByIds.
page: 2: This indicates the page number for pagination. It’s requesting the second page of results.
filter: { name: “Morty” }: This applies a filter to the query, so it only returns characters whose name is “Morty”.
4.4 Fetching Data From the GraphQL API Endpoint in React Components
useQuery Hook: It is a built-in hook provided by the @apollo/client to execute queries and get data in React.
// src/App.tsx
import { useQuery } from "@apollo/client";
import { GET_CHARACTERS } from "./graphql/queries";
function App() {
const { loading, error, data } = useQuery(GET_CHARACTERS);
if (loading) return Loading...
;
if (error) return Error: {error.message}
;
const resData = data.characters.results;
return (
User List
{resData.map((data: { name: string }) => {
return - {data.name}
;
})}
);
}
export default App;
The useQuery hook returns an object from Apollo Client on rendering of the component with loading, error, and data.
The component shows a “Loading…” message while loading the response after checking the loading state.
An error message is displayed if a response fails to reach due to some unexpected events.
This field lets you access the requested information rendered within the React component on successful retrieval.
4.5 Create a GraphQL Mutation to Add Data
Note: This free API is not provided to add or update records, but we can create a new record via the example mutation below.
// src/graphql/queries.ts
import { gql } from "@apollo/client";
export const CREATE_USER_MUTATION = gql`
mutation CreateUser($firstname: String!, $lastname: String!) {
createUser(firstname: $firstname, lastname: $lastname) {
id
firstname
lastname
}
}
`;
Mutation: This keyword defines that the operation is a GraphQL mutation (which is used to modify data on the server).
CreateUser: This is the name of the mutation. You can use this name for debugging or logging purposes.
($firstname: String!, $lastname: String!): These are the variables required by the mutation.
// src/AddUser.tsx
import React, { useState } from 'react';
import { useMutation, gql } from '@apollo/client';
import { CREATE_USER_MUTATION } from "./graphql/queries";
const CreateUser = () => {
const [firstname, setFirstname] = useState('');
const [lastname, setLastname] = useState('');
const [createUser, { data, loading, error }] = useMutation(CREATE_USER_MUTATION);
const handleSubmit = (e) => {
e.preventDefault();
createUser({ variables: { firstname, lastname } });
};
return (
Create User
);
};
export default CreateUser;
We use Apollo Client’s useMutation hook to send a GraphQL mutation request to the server when a user is created.
useMutation: This hook is used to trigger a GraphQL mutation. It returns an array with two elements.
createUser: This is a function you call to trigger the mutation. You pass variables to this function (in this case, firstname and lastname) when the form is submitted.
data: This holds the result of the mutation after it successfully completes (i.e., the new user’s data, such as id, firstname, lastname).
loading: This is a boolean that indicates whether the mutation is in progress.
error: This holds any error that may have occurred while trying to execute the mutation.
4.6 Fetching Data with GraphQL Queries without Apollo Client
This is a manual way of fetching data using GraphQL without Apollo Client. You send the GraphQL query using fetch(). Handle the response yourself. Manage loading, error, and rendering logic using React state.
import { useEffect, useState } from "react";
import { GET_CHARACTERS } from "./graphql/queries";
function App() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch("https://rickandmortyapi.com/graphql", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
query: GET_CHARACTERS_QUERY,
}),
});
const json = await response.json();
if (json.errors) {
throw new Error(json.errors[0].message);
}
setData(json.data);
} catch (err: any) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchData();
}, []);
if (loading) return Loading...
;
if (error) return Error: {error}
;
const resData = data.characters.results;
return (
User List
{resData.map((item: { name: string }, index: number) => (
- {item.name}
))}
);
}
export default App;
4.7 Modification of Server-Side Data with GraphQL Mutations without Apollo Client
This is the manual way to perform GraphQL mutations (e.g., creating a user) without Apollo Client.
import React, { useState } from 'react';
import { CREATE_USER_MUTATION } from "./graphql/queries";
const CreateUser = () => {
const [firstname, setFirstname] = useState('');
const [lastname, setLastname] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [user, setUser] = useState(null);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
setError(null);
try {
const response = await fetch('https://rickandmortyapi.com/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: CREATE_USER_MUTATION,
variables: { firstname, lastname },
}),
});
const json = await response.json();
if (json.errors) {
throw new Error(json.errors[0].message);
}
setUser(json.data.createUser);
} catch (err: any) {
setError(err.message);
} finally {
setLoading(false);
}
};
return (
Create User
{error && Error: {error}
}
{user && (
User Created:
ID: {user.id}
Name: {user.firstname} {user.lastname}
)}
);
};
export default CreateUser;
5. GraphQL Libraries For React
There are multiple JavaScript client libraries in the market. To make this a little easier, we’ll discuss five top JavaScript GraphQL client libraries. We’ll discuss their characteristics, advantages, and disadvantages, giving you a wholesome overview. So let’s start.
5.1 Apollo Client
Apollo Client is the most used GraphQL library written in TypeScript. You can use it to manage local and remote states without Redux.
Features:
- Declarative Data Fetching: You can receive the required data by writing a single query from the front end without the need to track loading states manually.
- Integration Support: Apollo Client has built-in integration support for frontend libraries and frameworks such as React, React Native, Angular, Next.js, and Vue.js.
- Flexible Client Configuration: You can configure error handling, catching, and data fetching strategies as per your requirements.
- Error Handling and Retry Logic: The library includes built-in error-handling mechanisms and retry policies to handle network errors.
- Developer Tools: Tools like Chrome / Firefox DevTools, VS Code, and Apollo DevTools browser extension streamline the development and debugging.
Pros:
- Rich Ecosystem and Tooling: You get access to numerous tools and plugins, improving the development experience and productivity.
- Enhanced User Experience: Apollo provides offline support and an optimistic user interface, improving the user experience.
- Community Support: There’s extensive community support contributing to online support, documentation, tutorials, tools, plugins, etc.
Cons:
- Memory Overhead: The caching mechanism increases the memory consumption in complex React applications.
- Increased Bundle Size: There’s a possibility that your application’s bundle size may increase with Apollo Client as it has 14 extra dependencies, resulting in increased load times.
- Steep Learning Curve: Beginners may find GraphQL and Apollo Client’s difficult concepts quite challenging to understand.
5.2 Relay
Relay is a GraphQL client JavaScript framework for React developed by Facebook. It leverages the composability of React components for data fetching.
Features:
- Declarative Data: The components just declare their data needs, and Relay makes their pre-loadable queries.
- Type Safety: Errors in code are detected at compile time, as Relay generates type definitions to resolve errors statically.
- Pre-Fetching: Relay provides the flexibility to fetch queries before the code downloads or runs.
- Streaming and Deferred Data: Declaratively defer parts of your query, and Relay will progressively re-render the UI as the data streams in.
- UI Patterns: Relay implements UI behaviors like optimistic updates, loading states, refetching, pagination, rollbacks, and many more.
Pros:
- Predictable State Management: You can build predictable UIs as Relay ensures that components receive exactly the data they need.
- Performance Optimization: Fetching only necessary data for each component reduces bandwidth consumption and decreases loading time.
Cons:
- Complex Setup: It’s quite difficult to configure and takes time to learn the framework.
- Tight Coupling with GraphQL: Relay requires only a GraphQL server, making it unsuitable for applications using other servers.
- Low Integration Support: Relay supports only React and React Native, and no other frontend frameworks.
5.3 Graphql-request
Graphql-request is the most lightweight and minimal JavaScript GraphQL client supporting Node.js and browsers.
Features:
- SSR Support: Graphql-request seamlessly fetches data on the server side, regardless of the SSR framework you’re using.
- Type Checking: TypeScript support in graphql-request allows strong type-checking, resulting in early error detection and correction.
Pros:
- Community Support: Graphql-request has a large and active community support.
- Lightweight: It has just two dependencies, reducing the bundle size.
- Easy to Use: Write a few lines of code to make a GraphQL request without any particular configurations, objects, or intricacies.
Cons:
- Lack of Documentation: There’s only a short README.md file to refer to regarding graphql-request.
- No Advanced Features: Graphql-request lacks support for query caching, pagination, subscriptions, deduplication, etc.
5.4 URQL
Universal React Query Library (URQL) is a customizable and versatile JavaScript GraphQL client for React.
Features:
- Performant and Functional: URQL can be easily used with React, Svelte, and Preact owing to its lightweight nature.
- Easily Extensible: URQL supports a kind of middleware called Exchanges to change fetching, caching, and subscribing to data.
- Easy to Use: A beginner as well as a proficient GraphQL user can use URQL as it prioritizes adaptability and usability.
Pros:
- Integration Support: URQL provides framework bindings for React, Preact, Svelte, and Vue through packages like urql, @urql/preact, @urql/svelte, and @urql/vue, respectively.
- Easy Configuration: Unlike Relay and Apollo, URQL allows for simpler configurations without facing many complications.
- Offline Support: URQL offers built-in offline support for offline usage.
Cons:
- Small Community: URQL has a new and growing user base, hence, less community support.
- Lack of Advanced Functionalities: It does not support features like deduplication, pagination, query batching, etc.
5.5 GraphQL-Hooks
GraphQL-hooks is a JavaScript library with first-class support for hooks. It includes useMutation, useSubscription, and useQuery React Hooks to deal with queries, mutations, and subscriptions, respectively.
Features:
- Lightweight: The bundle size is smaller as there are limited extra dependencies.
- Excellent Caching Support: The plugin named graphql-hooks-memcache provides in-memory caching.
- TypeScript Support: The library is written in TypeScript hence, client methods can give type details for query variables, response data, and error responses.
Pros:
- Advanced Features Support: GraphQL Hooks support server-side rendering, persisted queries, pagination, refetching, and GraphQL subscriptions.
- Extensible: Plugins in GraphQL-hooks make it easy to extend.
- Easy Loading: The small package size reduces the data loading time and facilitates quick error handling.
Cons:
- Limited to React: GraphQL-hooks does not support other JavaScript libraries and frameworks like Apollo Client.
- Small Community: The community size is less, therefore low support in terms of tutorials, plugins, etc.
6. Final Thoughts
GraphQL has emerged as an effective alternative to REST while working with APIs. When it comes to integrating it with React applications, there are multiple libraries we studied above. However, Apollo Client is the most embraced library amongst the developer community owing to its helpful properties like caching and error handling. Therefore, we’ve comprehensively covered the integration process to help you sail through the entire journey of API handling in React.
The above article is a comprehensive document where we’ve tried to get deep into all the intricacies of GraphQL integration with a React app. We’ve explained how Apollo Client can facilitate this integration and even fetch and modify data without it. Now, you have to read this guide thoroughly and implement the learned things practically to get a thorough with the concepts.
Comments