Querying for Users
Learn to enable querying for union types in a React application.
We'll cover the following...
A new page
In order to query for users, let’s create a brand new page within our application. We will create a new file at pages/users/[username].tsx
for this. This page will be matched by an address such as http://*address_to_app*/users/radar12
. Here is the code that we will put on this page:
import { useRouter } from "next/router";import { ApolloProvider } from "@apollo/client";import client from "client";import UserProfile from "components/Users/UserProfile";function User(){const router = useRouter();const { username } = router.query;return (<ApolloProvider client={client}><UserProfile username={username as string} /></ApolloProvider>);}export default User;
This page uses the useRouter
hook from next/router
to load the username
from the route. The component then wraps another component called UserProfile
in the same ApolloProvider
and Layout component that we used in our pages/index.tsx
file. The ApolloProvider
component allows us to run GraphQL queries within the UserProfile
component.
Let’s go ahead and create that new file for a component now. Rather than starting with a component this time, we’ll start with the GraphQL query and then use what that returns to inform the shape of our component. Let’s add the GraphQL query to a new file.
import gql from "graphql-tag";const userQuery = gql`query user($username: String!) {result: user(username: $username) {... on SuspendedUser {idusernamesuspensionReason}... on User {idusername}}}`;
Running GraphQL Code Generator with only the query present in our component's file generates the following src/generated/graphql.tsx
file.
import { gql } from '@apollo/client';import * as Apollo from '@apollo/client';export type Maybe<T> = T | null;export type InputMaybe<T> = Maybe<T>;export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };const defaultOptions = {}/** All built-in and custom scalars, mapped to their actual values */export type Scalars = {ID: string;String: string;Boolean: boolean;Int: number;Float: number;/** The `Upload` scalar type represents a file upload. */Upload: any;};export type Book = {__typename?: 'Book';id: Scalars['ID'];title: Scalars['String'];};export enum CacheControlScope {Private = 'PRIVATE',Public = 'PUBLIC'}export type Mutation = {__typename?: 'Mutation';createBook: Book;updateBookTitle: Book;};export type MutationCreateBookArgs = {title: Scalars['String'];};export type MutationUpdateBookTitleArgs = {id: Scalars['ID'];title: Scalars['String'];};export type Query = {__typename?: 'Query';book: Book;books: Array<Book>;booksWithTitle: Array<Book>;user: UserResult;};export type QueryBookArgs = {id: Scalars['ID'];};export type QueryBooksWithTitleArgs = {title: Scalars['String'];};export type QueryUserArgs = {username: Scalars['String'];};export type SuspendedUser = {__typename?: 'SuspendedUser';id: Scalars['ID'];suspensionReason: Scalars['String'];username: Scalars['String'];};export type User = {__typename?: 'User';id: Scalars['ID'];username: Scalars['String'];};export type UserResult = SuspendedUser | User;export type UserQueryVariables = Exact<{username: Scalars['String'];}>;export type UserQuery = { __typename?: 'Query', result: { __typename?: 'SuspendedUser', id: string, username: string, suspensionReason: string } | { __typename?: 'User', id: string, username: string } };export const UserDocument = gql`query user($username: String!) {result: user(username: $username) {... on SuspendedUser {idusernamesuspensionReason}... on User {idusername}}}`;/*** __useUserQuery__** To run a query within a React component, call `useUserQuery` and pass it any options that fit your needs.* When your component renders, `useUserQuery` returns an object from Apollo Client that contains loading, error, and data properties* you can use to render your UI.** @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;** @example* const { data, loading, error } = useUserQuery({* variables: {* username: // value for 'username'* },* });*/export function useUserQuery(baseOptions: Apollo.QueryHookOptions<UserQuery, UserQueryVariables>) {const options = {...defaultOptions, ...baseOptions}return Apollo.useQuery<UserQuery, UserQueryVariables>(UserDocument, options);}export function useUserLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<UserQuery, UserQueryVariables>) {const options = {...defaultOptions, ...baseOptions}return Apollo.useLazyQuery<UserQuery, UserQueryVariables>(UserDocument, options);}export type UserQueryHookResult = ReturnType<typeof useUserQuery>;export type UserLazyQueryHookResult = ReturnType<typeof useUserLazyQuery>;export type UserQueryResult = Apollo.QueryResult<UserQuery, UserQueryVariables>;
We can see that in lines 126–129, a new ...