How to use GraphQL on the Client-side with React and TypeScript
Tags: tutorial, webdev, javascript, graphql
Published: 2021-01-25 23:29:55

---
title: How to use GraphQL on the Client-side with React and TypeScript
published: true
description: 
series: TypeScript + GraphQL + TypeGraphQL
tags: tutorial, webdev, javascript, graphql
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/qfyfayquik9rcmi5a79d.png
canonical_url: https://www.takeshape.io/articles/how-to-use-graphql-on-the-client-side-with-react-and-typescript/
---

In this tutorial, we will be looking at using GraphQL on the client-side with React, TypeScript, and Apollo Client. This article is a follow-up of [How to use TypeScript with GraphQL (server-side)](https://www.takeshape.io/articles/how-to-use-typescript-with-graphql/) in which we built a GraphQL API using TypeScript and TypeGraphQL. We’ll be using the API we created in that article, so if you haven’t already, you may want to catch up before diving into the client-side because. Let’s get started!

## Prerequisites

This guide assumes that you have basic experience with React and TypeScript. You will learn how to use GraphQL in a React App to interact with a GraphQL API and then retrieve the data using Apollo Client. We’ll be building a Todo App that relies on the API to add and fetch the Todos.

You can preview the GraphQL API in this [CodeSandbox](https://codesandbox.io/s/typegraphql-api-tyoku)

## Setting up

To start a new React App, execute this command on the command-line-interface (CLI):

```bash
npx create-react-app react-typescript-graphql
```

Next, we have to install the Apollo and GraphQL libraries. The Apollo Client will allow us to communicate with a GraphQL API. Open the React App directory in your CLI and run the following command:

```bash
yarn add apollo-boost @apollo/react-hooks graphql
```

Or for `npm`

```bash
npm install apollo-boost @apollo/react-hooks graphql
```

Now let’s structure the project as follows:

```bash
src
| ├── components
| |  ├── AddTodo.tsx
| |  └── Todo.tsx
| ├── type
| |  └── Todo.ts
| ├── App.tsx
| ├── useRequest.ts
| ├── graphql.ts
| ├── index.ts
| └── index.css
```

There are two files to take special notice of:

- `useRequest.ts` is a custom hook that helps fetch data using Apollo Client.
- `graphql.ts` holds the GraphQL logic to interact with the API.

With this folder structure in place, we can get our hands dirty and create our TypeScript Types!

## Creating the TypeScript Types

**types/Todo.ts**

```tsx
export interface ITodo {
  id?: string;
  title: string;
  description: string;
}

export interface ITodos {
  getTodos: ITodo[];
}

export type ITodoMutation = {
  addTodo: ITodo;
};
```

Let’s explore what each type describes. The `ITodo` type describes the shape of a Todo. We use the `ITodo` type to create `ITodos` which returns an array of Todos from the API. Finally, we rely on `ITodo` to define the type expected by the GraphQL mutation query `ITodoMutation`.

Next we’ll add Apollo Client into our React App.

## Connecting React to Apollo Client

**index.ts**

```tsx
import * as React from "react";
import { render } from "react-dom";
import ApolloClient from "apollo-boost";
import { ApolloProvider } from "@apollo/react-hooks";

import App from "./App";

const client = new ApolloClient({
  uri: "https://tyoku.sse.codesandbox.io/graphql"
});

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

After importing `ApolloClient`, we create a new instance of it and pass in the URL of the GraphQL API. To connect it with React, we need to pass the `client` object to the `ApolloProvider` component. Apollo client can now be used to retrieve data from the API.

Next we’ll use `gql` and the hooks provided by Apollo Client to send the GraphQL queries to the API.

## Writing the GraphQL queries

**graphql.ts**

```tsx
import gql from "graphql-tag";

export const GET_TODOS = gql`
  {
    getTodos {
      id
      title
      description
      status
    }
  }
`;

export const ADD_TODO = gql`
  mutation AddTodo($title: String!, $description: String!) {
    addTodo(todoInput: { title: $title, description: $description }) {
      id
      title
      description
      status
    }
  }
`;
```

As you can see, `GET_TODOS` is a GraphQL Query for retrieving all Todos from the API and a GraphQL Mutation `ADD_TODO` for adding a new Todo. The mutation query expects a `title`, and a `description` in order to create a new Todo on the backend.

## Fetching the Todos from the GraphQL API

**useRequest.ts**

```tsx
import { DocumentNode, useQuery, useMutation } from "@apollo/react-hooks";
import { ITodos, ITodoMutation } from "./types/Todo";

export function useTodoQuery(gqlQuery: DocumentNode) {
  const { loading, error, data } = useQuery<ITodos>(gqlQuery);
  return { loading, error, data };
}

export function useTodoMutation(gqlQuery: DocumentNode) {
  const [addTodo] = useMutation<ITodoMutation>(gqlQuery);
  return [addTodo];
}
```

This custom hook is optional. You can skip it and use the Apollo hooks directly in your components.

In this file, we first have a function `useTodoQuery` that expects a GraphQL Query to fetch all Todos from the API and then returns the data. Next, we use the `useTodoMutation` method to create a new Todo based on the data received as a parameter.

So far, we have connected React and Apollo and created the GraphQL queries to access the API. Next, let’s build the React components to that will consume the returned data.

## Creating the components

**components/Todo.ts**

```tsx
import * as React from "react";
import { ITodo } from "../types/Todo";

type Props = {
  todo: ITodo;
};

const Todo: React.FC<Props> = ({ todo }) => {
  const { title, description } = todo;

  return (
    <div className="Card">
      <h1>{title}</h1>
      <span>{description}</span>
    </div>
  );
};

export default Todo;
```

The `Todo` component is responsible for the display of a Todo object. It receives the data of type `Itodo` and then uses destructuring (JavaScript expression for unpacking values from arrays or objects into distinct variables.) to pull out the `title` and the `description` of the Todo.

**components/AddTodo.ts**

```tsx
import * as React from "react";
import { ApolloCache } from "@apollo/react-hooks";
import { FetchResult } from "apollo-boost";

import { useTodoMutation } from "../useRequest";
import { ADD_TODO, GET_TODOS } from "../graphql";
import { ITodo, ITodoMutation, ITodos } from "../types/Todo";

const AddTodo: React.FC = () => {
  const [formData, setFormData] = React.useState<ITodo | {}>();
  const [addTodo] = useTodoMutation(ADD_TODO);

  const handleForm = (e: React.FormEvent<HTMLInputElement>) => {
    setFormData({
      ...formData,
      [e.currentTarget.id]: e.currentTarget.value
    });
  };

  const handleSaveTodo = (
    e: React.FormEvent,
    { title, description }: ITodo | any
  ) => {
    e.preventDefault();
    addTodo({
      variables: { title, description },
      update: (
        cache: ApolloCache<ITodoMutation>,
        { data: { addTodo } }: FetchResult<ITodoMutation>
      ) => {
        const cacheData = cache.readQuery({ query: GET_TODOS }) as ITodos;
        cache.writeQuery({
          query: GET_TODOS,
          data: {
            getTodos: [...cacheData.getTodos, addTodo]
          }
        });
      }
    });
  };

  return (
    <form className="Form" onSubmit={(e) => handleSaveTodo(e, formData)}>
      <div>
        <div>
          <label htmlFor="name">Title</label>
          <input onChange={handleForm} type="text" id="title" />
        </div>
        <div>
          <label htmlFor="description">Description</label>
          <input onChange={handleForm} type="text" id="description" />
        </div>
      </div>
      <button>Add Todo</button>
    </form>
  );
};

export default AddTodo;
```

After importing the `useTodoMutation` hook into our component, we pass in the GraphQL mutation query `ADD_TODO` as an argument. Next, we handle the data entered by the user with the `handleForm` function and `useState`. Once the user submits the form, we call the `addTodo` method to create the Todo with the mutation query. To preview the Todo created, we need to update the Apollo cache by spreading the old Todos with the new one in an array of Todos.

We are now able to create and display a list of Todos. Finally, let’s put it all together and use the components in the `App.ts` file.

## Showing the Todos

**App.ts**

```tsx
import * as React from "react";
import "./styles.css";

import { GET_TODOS } from "./graphql";
import { useTodoQuery } from "./useRequest";
import AddTodo from "./components/AddTodo";
import Todo from "./components/Todo";
import { ITodo } from "./types/Todo";

const App: React.FC = () => {
  const { loading, error, data } = useTodoQuery(GET_TODOS);

  if (loading) return <h1>Loading...</h1>;
  if (error) return <h1>Something went wrong!</h1>;

  return (
    <div className="App">
      <h1>My Todos</h1>
      <AddTodo />
      {data.getTodos.map((todo: ITodo) => (
        <Todo key={todo.id} todo={todo} />
      ))}
    </div>
  );
};

export default App;
```

In this `App` component, we use the `useTodoQuery` hook to retrieve all Todos from the GraphQL API. Next, we loop through the response data and display it using the `Todo` component.

With this step, the app is ready to be tested on the browser. Open the project directory in the CLI and run this command:

```bash
yarn start
```

Or

```bash
npm start
```

If everything works as expected, you should be able to see the React app here: [http://localhost:3000/](http://localhost:3000/).

![https://paper-attachments.dropbox.com/s_97BE7739B2275450FC3A3714142956FE1D1377B65D8BD847EAB462957E492AD1_1603457616031_app-preview.PNG](https://paper-attachments.dropbox.com/s_97BE7739B2275450FC3A3714142956FE1D1377B65D8BD847EAB462957E492AD1_1603457616031_app-preview.PNG)

app-preview

And that’s it! Our React app is looking good!

We’ve built a Todo App with React, TypeScript, GraphQL, and Apollo Client. You can preview the finished project in this [CodeSandbox](https://codesandbox.io/s/react-graphql-typescript-54uye).

## Conclusion

In this tutorial, we learned how to use GraphQL on the client-side with React, TypeScript, and Apollo Client. We also used the GraphQL API built with TypeGraphQL as a backend to finish up with a full-stack strongly-typed app. A very exciting stack to try on your next project!

## Resources

Check out these resources to dive deeper into the content of this tutorial:

- [Apollo Client React Docs](https://www.apollographql.com/docs/react/)
- [React TypeScript Docs](https://www.typescriptlang.org/docs/handbook/react.html)
- [GraphQL Basics](https://graphql.org/learn/)