GraphQL + React App with TypeScript

Building a Client-Side Application with React, Apollo, and GraphQL

Why GraphQL + TypeScript?

GraphQL is a query language for APIs that allows clients to request specific data, reducing the amount of data transferred over the network. TypeScript is a statically typed JavaScript superset that helps catch errors early and improves code maintainability. Together, they provide a powerful combination for building robust and efficient applications.

Getting Started with TypeScript, React, and GraphQL

To start, we will create a new React project using create-react-app with the TypeScript template:

npx create-react-app my-app --template typescript

We will then install the necessary dependencies, including @apollo/client and graphql:

npm install @apollo/client graphql

Writing GraphQL Queries and Generating Types

We will write two GraphQL queries: one to fetch a list of launches and another to fetch detailed information about a single launch. We will use the graphql-tag library to define our queries and the graphql-code-generator library to generate TypeScript types for our queries.

query Launches {
  launches {
    id
    name
  }
}

query Launch($id: ID!) {
  launch(id: $id) {
    id
    name
    details
  }
}

Initializing Apollo Client

We will initialize the Apollo client and use the ApolloProvider component to add our client to React’s context:

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

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

function App() {
  return (
    <ApolloProvider client={client}>
      {/* app content */}
    </ApolloProvider>
  );
}

Building Our Components

We will create two components: LaunchList and LaunchProfile. The LaunchList component will display a list of launches, and the LaunchProfile component will display detailed information about a single launch.

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

const LAUNCHES_QUERY = gql`
  query Launches {
    launches {
      id
      name
    }
  }
`;

function LaunchList() {
  const { data, loading, error } = useQuery(LAUNCHES_QUERY);

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

  return (
    <ul>
      {data.launches.map(launch => (
        <li key={launch.id}>{launch.name}</li>
      ))}
    </ul>
  );
}

Adding User Interaction

We will add functionality to fetch the full launch data when a user clicks on an item in the launch list. We will use the useState hook to maintain and update the state of the selected launch ID.

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

const LAUNCH_QUERY = gql`
  query Launch($id: ID!) {
    launch(id: $id) {
      id
      name
      details
    }
  }
`;

function LaunchProfile() {
  const [selectedLaunchId, setSelectedLaunchId] = useState(null);

  const { data, loading, error } = useQuery(LAUNCH_QUERY, {
    variables: { id: selectedLaunchId },
  });

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

  return (
    <div>
      

{data.launch.name}


      <p>{data.launch.details}</p>
    </div>
  );
}

Code Generation and TypeScript

One of the key benefits of using GraphQL and TypeScript is the ability to generate types automatically. This eliminates the need for manual type definitions and reduces the risk of type-related errors.

Next Steps

To take this application further, we could add pagination to the launch list and explore more data connectivity using additional fields from the SpaceX GraphQL API.

Leave a Reply