This is a booking website for a company's internal booking management. It is a practice project for the book React Hooks in Action by JOHN LARSEN.
The entire application is divided into four categrouies of components: Bookables, Bookings, Users and UI
- The App component is the root component for the application. It displays the header with its links and user-picker drop-down
- The App component also sets up routes to the three main pages, Bookings, Bookables and Users.
- The BookablesPage component is the parent of all other Bookables components.
- The BookablesView component manages the state of which bookable is currently selected using
useState
hook and pass down the state along with the update function to its children. - The BookablesList component display a list of all available facilities to book with a dropdown list and a "Next" button for stepping through all the bookables.
- The BookingsPage component is the parent of all other Bookings components.
- The BookingsPage component manages the state of which bookable is currently selected using
useState
hook and pass down the state along with the update function to its children. - The BookablesList component is reused for the same purpose as before.
- The Bookings component contains the WeekPicker component which is for users to choose a range of date and the BookingsGrid component.
- The BookingsGrid component generates a date-seesion table for the selected bookable calling the grid-builder function.
- Live Site: Booking-site
- CSS custom properties
- CSS Flexbox and Grid for layout
- React hooks for React component state management
- React - JS library
- Create React App - CRA for React build setup
- My JSON Server - Mock API for serving JSON data
-
Functionality that could be shared means we can extarct it into a custom hook. In this example code below, the data fetching function is encapsulated within a custom hook called
useFetch
.import { useState, useEffect } from 'react'; import { getData } from './api'; export default function useFetch(url) { const [data, setData] = useState(); const [error, setError] = useState(null); const [status, setStatus] = useState('idle'); useEffect(() => { let doUpdate = true; setStatus('loading'); setData(undefined); setError(null); getData(url) .then((data) => { if (doUpdate) { setData(data); setStatus('success'); } }) .catch((error) => { if (doUpdate) { setStatus('error'); setError(error); } }); return () => (doUpdate = false); }, [url]); return { data, status, error }; }
-
Before rerunning an effect, React calls any associated cleanup function for the previous invocation of the effect, in this case the cleanup function
return () => (doUpdate = false)
makes the in-flight data invalid.useEffect(() => { let doUpdate = true; setStatus('loading'); setData(undefined); setError(null); getData(url) .then((data) => { if (doUpdate) { setData(data); setStatus('success'); } }) .catch((error) => { if (doUpdate) { setStatus('error'); setError(error); } }); return () => (doUpdate = false); }, [url]);
- Rewrite with TypeScript
- Beautify website using Material-UI
- React hooks - React offical tutorial for hooks.
- How to call an async function inside a UseEffect() in React - A helpful explaination about async function inside useEffect hook.
- GitHub - Haoliang Zhang
- LinkedIn - Haoliang Zhang