Reader small image

You're reading from  Learn React with TypeScript - Second Edition

Product typeBook
Published inMar 2023
Reading LevelBeginner
PublisherPackt
ISBN-139781804614204
Edition2nd Edition
Languages
Tools
Right arrow
Author (1)
Carl Rippon
Carl Rippon
author image
Carl Rippon

Carl Rippon has been in the software industry for over 20 years developing a complex lines of business applications in various sectors. He has spent the last 8 years building single-page applications using a wide range of JavaScript technologies including Angular, ReactJS, and TypeScript. Carl has also written over 100 blog posts on various technologies.
Read more about Carl Rippon

Right arrow

Interacting with RESTful APIs

In this chapter, we will build a page that lists blog posts fetched from a REST API, as well as also a form to submit blog posts to the REST API. Through this, we will learn about various approaches to interacting with a REST API from a React component.

The first approach will be using React’s useEffect hook with the browser’s fetch function. As part of this process, we learn how to use a type assertion function to strongly type the data from a REST API. We will then use the data loading capability of React Router and experience its benefits. After that, we will move on to use a popular library called React Query and experience its benefits, before using React Query and React Router together to get the best of both these libraries.

So, in this chapter, we’ll cover the following topics:

  • Getting set up
  • Using the effect hook with fetch
  • Posting data with fetch
  • Using React Router
  • Using React Query
  • Using...

Technical requirements

We will use the following technologies in this chapter:

All the code snippets in this chapter can be found online at https://github.com/PacktPublishing/Learn-React-with-TypeScript-2nd-Edition/tree/main/Chapter9.

Creating the project

In this section, we will start by creating the project for the app we will build. We will then create a REST API for the app to consume.

Setting up the project

We will develop the app using Visual Studio Code and require a new Create React App-based project setup. We’ve previously covered this several times, so we will not cover the steps in this chapter – instead, see Chapter 3, Setting Up React and TypeScript.

We will style the app with Tailwind CSS. We have previously covered how to install and configure Tailwind in Create React App in Chapter 5, Approaches to Styling Frontends. So, after you have created the React and TypeScript project, install and configure Tailwind.

We will use React Router to load data, so see Chapter 6, Routing with React Router, for information on how to do this.

We will use React Hook Form to implement the form that creates blog posts, and the @tailwindcss/forms plugin to style the form. See Chapter 7, Working...

Using the effect hook with fetch

In this section, we will create a page that lists the blog posts returned from the REST API we just created. We will use the browser’s fetch function and React’s useEffect hook to interact with the REST API.

Getting blog posts using fetch

We will start by creating a function that gets blog posts from the REST API using the browser’s fetch function; we will store the API URL in an environment variable. To do this, carry out the following steps:

  1. The same URL will be used to get, as well as save, new blog posts to the REST API. We will store this URL in an environment variable. So, create a file called .env in the root of the project containing this variable, as follows:
    REACT_APP_API_URL = http://localhost:3001/posts/

This environment variable is injected into the code at build time and can be accessed by code using process.env.REACT_APP_API_URL. Environment variables in Create React App projects must be prefixed...

Posting data with fetch

In this section, we will create a form that submits a new blog post to our REST API. We will create a function that uses fetch to post to the REST API. That function will be called in the form’s submit handler.

Creating new blog posts using fetch

We will start by creating the function that sends a new blog post to the REST API. This will use the browser’s fetch function, but this time, using an HTTP POST request. Carry out the following steps:

  1. We will start by opening types.ts in the posts folder and adding the following two types:
    export type NewPostData = {
      title: string;
      description: string;
    };
    export type SavedPostData = {
      id: number;
    };

The first type represents a new blog post, and the second type represents the data from the API when the blog post is successfully saved.

  1. Create a new file called savePost.ts in the posts folder and add the following import statement:
    import { NewPostData...

Using React Router

In this section, we will learn about how React Router can integrate with the data-fetching process. We will use this knowledge to simplify the code that fetches blog posts in our app.

Understanding React Router data loading

React Router data loading is similar to React Router forms, which we learned about in Chapter 7. Instead of defining an action that handles form submission, we define a loader that handles data loading. The following code snippet defines a loader on a some-page route:

const router = createBrowserRouter([
  ...,
  {
    path: '/some-page',
    element: <SomePage />,
    loader: async () => {
      const response = fetch('https://somewhere');
      return await response.json();
    }
  },
  ...
]);

React Router calls the loader...

Using React Query

React Query is a popular library for interacting with REST APIs. The key thing it does is manage the state surrounding REST API calls. One thing that it does that React Router doesn’t is that it maintains a cache of the fetched data, which improves the perceived performance of an app.

In this section, we will refactor the app to use React Query rather than React Router’s loader capability. We will then refactor the app again to use both React Query and React Router’s loader to get the best of both these worlds.

Installing React Query

Our first job is to install React Query, which we can do by running the following command in a terminal:

npm i @tanstack/react-query

This library includes TypeScript types, so no additional package is required to be installed.

Adding the React Query provider

React Query requires a provider component in the component tree above the components that need access to the data it manages. Eventually...

Using React Router with React Query

So far, we have experienced the benefits of both React Router and React Query data fetching. React Router reduces the number of re-renders, while React Query provides a client-side cache of the data. In this section, we will use these libraries together in our app so that it has both these benefits.

Carry out the following steps:

  1. Start by opening App.tsx and change the loader function on the route definition to the following:
    const router = createBrowserRouter([
      {
        path: '/',
        element: ...,
        loader: async () => {
          const existingData = queryClient.getQueryData([
            'postsData',
          ]);
          if (existingData) {
            return defer({ posts: existingData });
      ...

Summary

In this chapter, we used the browser’s fetch function to make HTTP GET and POST requests. The request’s URL is the first argument on the fetch function. The second argument on fetch allows the request options to be specified, such as the HTTP method and body.

A type assertion function can be used to strongly type the data in the response body of an HTTP request. The function takes in the data having an unknown type. The function then carries out checks to validate the type of data and throws an error if it is invalid. If no errors occur, the asserted type for the data is specified in the functions assertion signature.

React’s useEffect hook can be used to execute a call to fetch data from a backend API and store the data in the state when the component is mounted. A flag can be used inside useEffect to ensure the component is still mounted after the HTTP request before the data state is set.

React Query and React Router replace the use of useEffect...

Questions

Answer the following questions to check what you have learned in this chapter:

  1. The following effect attempts to fetch data from a REST API and store it in the state:
    useEffect(async () => {
      const response = await fetch('https://some-rest-api/');
      const data = await response.json();
      setData(data);
    }, []);

What are the problems with this implementation?

  1. The following fetching function returns an array of first names:
    export async function getFirstNames() {
      const response = await fetch('https://some-    firstnames/');
      const body = await response.json();
      return body;
    }

However, the return type of the function is any. So, how can we improve the implementation to have a return type of string[]?

  1. In the fetch function argument, what should be specified in the method option for it to make an HTTP PUT request?
    fetch(url, {
      method: ???,
      body...

Answers

  1. There are two problems with the implementation:
    • useEffect doesn’t support top-level async/await
    • If the component is umounted during the HTTP request, an error will occur when the data state is set

Here is an implementation with those issues resolved:

useEffect(() => {
  let cancel = false;
  fetch('https://some-rest-api/')
    .then((response) => data.json())
    .then((data) => {
      if (!cancel) {
        setData(data);
      }
    });
  return () => {
    cancel = true;
  };
}, []);
  1. An assert function can be used on the response body object as follows:
    export async function getFirstNames() {
      const response = await fetch('https://some-    firstnames/');
      const body = await response...
lock icon
The rest of the chapter is locked
You have been reading a chapter from
Learn React with TypeScript - Second Edition
Published in: Mar 2023Publisher: PacktISBN-13: 9781804614204
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Carl Rippon

Carl Rippon has been in the software industry for over 20 years developing a complex lines of business applications in various sectors. He has spent the last 8 years building single-page applications using a wide range of JavaScript technologies including Angular, ReactJS, and TypeScript. Carl has also written over 100 blog posts on various technologies.
Read more about Carl Rippon