The useState Hook
Though we've been able to create a custom fetch() function to help us make the GraphQL requests to query listings or delete a certain listing, we've only seen the results of our requests in our browser console. In this lesson, we'll introduce and use React's useState Hook to track listings state value in our function component with which we'll be able to use and display in our UI.
📝 This lesson's quiz can be found - here. 🗒️ Solutions for this lesson's quiz can be found - here. 📃 Grab a cheatsheet for the different ways the React
useState
Hook can be used - here.
The useState
Hook is a special Hook that allows us to add React state to functional components. We're going to use the useState
Hook to keep track of the listings data from our query as part of the <Listings>
component state.
useState
#
In our Listings.tsx
component file, we'll import the useState
Hook from the React library.
import React, { useState } from "react";
We'll specify the useState
Hook at the top of the Listings
component and specify two values it will return - listings
and setListings
. Since we don't have an idea of what the initial data of our state object is going to be, we'll initialize it with null
.
export const Listings = ({ title }: Props) => {
const [listings, setListings] = useState(null);
// ...
};
The useState
Hook allows us to destructure two values.
The first value is the state value we want to create. In our case, we've called the state value we've created
listings
.The second value is a function used to update the state value. In our case, we've called the function to update
listings
-setListings()
.
The only argument that the useState
Hook accepts is the initial value of the state value being created. We've initialized the listings
value with null
.
We're destructuring the array useState
gives us into two values - listings
and setListings
. The useState
Hook is just a function that returns an array of two values. What we've written is equivalent to doing:
export const Listings = ({ title }: Props) => {
const listingsAndSetListings = useState(null);
const listings = listingsAndSetListings[0];
const setListings = listingsAndSetListings[1];
// ...
};
Instead of writing the above in three lines, we're able to group the use of useState
into a single line with array de-structuring, a feature introduced in ES6.
useState
and the Listing
type#
The useState
Hook often does a good job in inferring the type of state data depending on the initial value provided. If we take a look at the listings
state value at this moment in time, we can see that the TypeScript compiler recognizes the type of listings
as null
.

There's an issue here. When we initialize our state values, we often initialize them with null
or empty values. If we intend on using the listings
value later in our component when it's finally populated, TypeScript will emit a warning if we attempt to access a property from it or map through it because TypeScript recognizes the type of the listings
value as null
.
This is why the useState
Hook accepts a type argument that allows us to specify the type of the value being created. In this case, we would want to specify the type of the listings
state value is the array of the Listing
type we've created in the Listings/types.ts
file.
We'll first export the Listing
interface from the Listings/types.ts
file.
export interface Listing {
id: string;
title: string;
image: string;
address: string;
price: number;
numOfGuests: number;
numOfBeds: number;
numOfBaths: number;
rating: number;
}
And import the Listing
interface type in the Listings.tsx
component file.
import {
DeleteListingData,
DeleteListingVariables,
Listing,
ListingsData
} from "./types";
We'll then use the Listing
interface type to state that the listings
state value is to have a type of Listing[]
. Since we're initializing the listings
state value with null
, we'll state the type of the listings
state value as a union type of Listing[] | null
. This will mean that the listings
state value can either be of the Listing[]
type or the null
type.
export const Listings = ({ title }: Props) => {
const [listings, setListings] = useState<Listing[] | null>(null);
// ...
};
Query listings#
This page is a preview of TinyHouse: A Fullstack React Masterclass with TypeScript and GraphQL