React Tutorial: How to develop an application from scratch with modern libraries
Tags: react, javascript, webdev, tutorial
Published: 2023-09-26 17:09:46

## Introduction

In this step-by-step tutorial, we are going to learn how to develop a React web application from scratch using some of the most popular tools in the React ecosystem.

Specifically, we will use:

- Zustand for global state management
- React Query for data fetching and caching
- React Hook Form for form handling
- React Router for navigation
- React Hot Toast for showing notifications

The application we will build will simulate a hotel booking system, with a page to list hotels and a details page to book rooms in a specific hotel.

Here are some of the features we will implement:

- Fetch and display a list of hotels from an API
- Navigate to the detail page of a specific hotel
- Form to select dates and book a room
- Global state management for bookings
- Notifications on errors or successful bookings
- Form validations

So without further ado, let's get started!

## Preparing the project

The first thing we need to do is prepare our React project. For this, we will use `create-react-app` which will allow us to bootstrap quickly:

```
npx create-react-app hotel-reservations
```

This will generate the basic React project structure in a folder called `hotel-reservations`.

Next, we install the dependencies by running `npm install` inside that folder.

The dependencies we will use in this project are:

- zustand
- react-query
- react-hook-form
- react-router-dom
- react-hot-toast

So we install them by running:

```shell
npm install zustand react-query react-hook-form react-router-dom react-hot-toast
```

Our project is now setup and ready! We can now start coding.

## Global state with Zustand

First we are going to configure our global state using Zustand.

Zustand is a lightweight library for managing global state in React. It allows us to have a centralized store that can be accessed from any component to read and update state.

For this, we create a `store.js` file and add the following:

```js
import { create } from 'zustand'const useStore = create(() => ({reservations: [],addReservation: (hotel, dates) => {set(state => ({reservations: [...state.reservations, { hotel, dates }]}))}}))export default useStore
```

Basically we are creating a `useStore` hook that gives us access to the `reservations` global state and an `addReservation` action to add new bookings.

We can import and use this hook from any component in our app.

## Data fetching with React Query

Now we are going to take care of fetching data from an API. For this we will use React Query.

React Query allows us to perform data fetching, caching, and updating. It also handles loading, error and automatic revalidation states.

First, we create a `db.json` file with mock data:

```json
{"hotels": [{"id": 1,"name": "Hotel Sunshine","description": "Beachfront hotel with pool","image": "hotel-1.jpg"},{"id": 2,"name": "Hotel Mountain Spa","description": "Luxury hotel in the mountains","image": "hotel-2.jpg"}]}
```

Then, we create a script in `package.json` to spin up a dev server with that data:

```json
"server": "json-server --watch db.json --port 3001"
```

Now we can create our fetching function:

```js
// hotels.js
const fetchHotels = async () => {const response = await fetch('http://localhost:3001/hotels')if (!response.ok) {throw new Error('Network error')}return response.json()}export { fetchHotels }
```

And use it in our `HotelsList` component:

```jsx
// HotelsList.js
import { fetchHotels } from './hotels'import { useQuery } from 'react-query'export default function HotelsList() {const { data, error, isLoading } = useQuery('hotels', fetchHotels)// display data or loading/error statereturn (// JSX to display hotels)}
```

That's all we need to implement data fetching with React Query!

## Forms with React Hook Form

Now let's implement the booking form with React Hook Form.

React Hook Form allows us to build forms easily in React, with validations, error handling and state management.

First we create our `BookingForm` component:

```js
// BookingForm.js
import { useForm } from 'react-hook-form'function BookingForm() {const { register, handleSubmit, formState: { errors } } = useForm()const onSubmit = (data) => {// submit form}return (<form onSubmit={handleSubmit(onSubmit)}><input{...register('checkinDate', { required: true })}/>{errors.checkinDate && (<p>Checkin date required</p>)}// ...more inputs and validations</form>)}
```

We are registering the inputs so React Hook Form controls them, handling submit, and displaying any validation errors.

And that's all we need for powerful form handling with React Hook Form!

## Navigation with React Router

Now we are going to configure navigation between different views using React Router.

First, we wrap our app with a `<BrowserRouter>` in `index.js`.

Then, we create the routes in `App.js`:

```jsx
import { Routes, Route } from 'react-router-dom'function App() {return (<Routes><Route path="/" element={<h1>Hotels</h1>} /><Route path="/hotel/:id" element={<HotelDetails />} /></Routes>)}
```

Finally, we use the `useNavigate` hook inside our `HotelsList` to navigate to a hotel's detail view when clicked.

And that's all we need for navigation with React Router!

## Notifications with React Hot Toast

Lastly, we are going to add notifications using React Hot Toast.

React Hot Toast allows us to show popup messages very easily.

We import it in our `BookingForm` component:

```js
import { toast } from 'react-hot-toast'
```

And show a success notification when booking:

```js
// inside onSubmit
toast.success('Booking successful!')
```

We also wrap it in `<Toaster>` to make it work app-wide.

And that's all we need to show notifications! React Hot Toast handles the UI.

## Summary

In this article we have seen how to develop a React web application from scratch using:

- Zustand for global state
- React Query for data fetching
- React Hook Form for forms
- React Router for navigation
- React Hot Toast for notifications

We have learned how to:

- Setup a global store with Zustand
- Fetch data from an API with React Query
- Create a form with validations using React Hook Form
- Add navigation between views with React Router
- Show notifications to the user with React Hot Toast

These tools have allowed us to quickly build a React application in a straightforward, declarative way with great practices.

You can find the code in [this GitHub Repository](https://github.com/carlosazaustre/hotel-reservation-app) (You can give a Star ⭐️ if you like it)

{% embed https://github.com/carlosazaustre/hotel-reservation-app %}

Also, you can find this tutorial in video format (in spanish)
{% embed https://youtu.be/KRrzBkxxMbc?si=ztRnlpMlMK-wVBpX %}

I hope you found this tutorial useful! Don't forget to share it and follow me for more web development content. See you next time!