React setup

To set up our development environment, the first step will be the React setup. There are different options available to install React. If you already have an existing app and want to add React, you can install it using a package manager such as npm using this command:

npm init
npm install --save react react-dom

However, if you are starting a new project, the easiest way to get started is with the React Starter Kit. Just go to the Command Prompt and execute the following command to install the React Starter kit:

npm install -g create-react-app

This command will install and set up the local development environment by downloading all the required dependencies. There are a number of benefits to have your development environment with node, such as optimized production builds, installing libraries using simple npm or yarn commands, and such.

Once you have it installed, you can create your first app using the given command:

create-react-app seat-booking

It will create a frontend application and will not include any backend logic or integration. It is just frontend and hence you can integrate it with any backend technology or in your existing project.

The preceding command will take a while to download all dependencies and create the project, so keep patience.

Once the project is created, just go into that folder and run the server:

cd seat-booking
npm start

Once the server is started, you can access the application at http://localhost:3000.

The start kit is the best way to start with React. However, if you are an advanced user, you can manually configure your project by adding React dependencies using the following commands:

npm init
npm install --save react react-dom

For this sample seat booking app, we will use the create-react-app command.

The project structure will look as follows if you see it in the Visual Code editor:

The created app structure is good enough to get started, but for our seat booking app, we will need to organize our source code in a better package structure.

So, we will create the different folders for actions, components, containers, and reducers, as shown in the following screenshot. For now, just focus on the components folder, because in that, we will put our React components. The rest of the folders are related to Redux, which we will see in the Redux section:

It is very important to identify the components at the start of application development so that you can have a better code structure.

Just to start with, we will have the following React components in our seat booking application:

  • Seat: Seat Object and basic building block of the application
  • SeatRow: It represents a row of seats
  • SeatList: It represents the list of all seats
  • Cart: It represents the cart that will have information on selected seats

Note that the design of components depends on the application complexity and data structure of the application.

Let's start with our first component called Seat. This will be under the components folder.

components/Seat.js:

import React from 'react'
import PropTypes from 'prop-types'

const Seat = ({ number, price, status }) => (
<li className={'seatobj ' + status} key={number.toString()}>
<input type="checkbox" disabled={status === "booked" ? true : false} id={number.toString()} onClick={handleClick}/>
<label htmlFor={number.toString()}>{number}</label>
</li>
)
const handleClick = (event) => {
console.log("seat selected " + event.target.checked);
}

Seat.propTypes = {
number:PropTypes.number,
price:PropTypes.number,
status:PropTypes.string
}

export default Seat;

Here, an important thing to note is that we are using JSX syntax, which we already saw in chapter 2, Integrate React App with Firebase.

Here, we have defined the Seat component with three properties:

  • number: refers to the number or ID given to that seat
  • price: refers to the amount to be charged to book this seat
  • status: refers to the seat status if it is booked or available

PropTypes in React is used to validate the inputs your component receives; for example, the price should be a number and not a String. A warning will be shown in the JavaScript console if an invalid value is provided for a prop. For performance reasons, PropTypes checking will only take place in the development mode.

In our seat booking app, when a user selects a seat, we need to add it to the cart so that the user can check out/book the ticket(s). To do so, we need to handle an onClick() for a seat. For now, we are just printing a console statement in the click handler function, but we will need to write a logic to push the selected seats to the cart. We will look into it in the later section when we will integrate Redux in our app.

If any seat is already booked, obviously we won't allow the user to select it and hence based on the status, we are disabling seats if they are booked.

Seat is our basic building block, and it will receive data from the parent component, which is the SeatRow component.

components/SeatRow.js:

import React from 'react'
import PropTypes from 'prop-types'
import Seat from './Seat';
const SeatRow = ({ seats, rowNumber }) => (
<div>
<li className="row">
<ol className="seatrow">
{seats.map(seat =>
<Seat key={seat.number} number={seat.number}
price={seat.price}
status={seat.status}
/>
)}
</ol>
</li>
</div>
)
SeatRow.propTypes = {
seats: PropTypes.arrayOf(PropTypes.shape({
number: PropTypes.number,
price: PropTypes.number,
status: PropTypes.string
}))
}
export default SeatRow;

A SeatRow represents a row of seats. We are creating loosely coupled components that can be maintained easily and can be reused wherever required. Here, we are iterating the array of seats JSON data to render corresponding Seat objects.

You can see in the preceding code block that we are validating our values using PropTypes. The PropTypes.arrayOf represents an array of Seats and PropTypes.shape represents the Seat object props.

Our next component is the SeatList component.

components/SeatList.js:

import React from 'react'
import PropTypes from 'prop-types'
const SeatList = ({ title, children }) => (

<div>
<h3>{title}</h3>
<ol className="list">
{children}
</ol>
</div>

)
SeatList.propTypes = {
children: PropTypes.node,
title: PropTypes.string.isRequired
}
export default SeatList;

Here, we have defined a SeatList component with two properties:

  • title: A title to be displayed for seat booking
  • children: It represents the list of Seats

There are two important things related to proptypes:

  • Proptypes.string.isRequired: isRequired can be chained to ensure that you see a warning in the console if the data received is not valid.
  • Proptypes.node: Node represents that anything can be rendered: number, string, elements, or an array (or fragment) containing these types.

The next and final component in our app is Cart.

components/Cart.js:

const Cart = () => {
return (
<div>
<h3>No. of Seats selected: </h3>
<button>
Checkout
</button>
</div>
)
}
export default Cart;

Our cart component will have a button called Checkout to book the tickets. It will also show the summary of the selected seats and total payment to be done. As of now, we are just putting a button and a label. We will modify it once we integrate Firebase and Redux in our app.

So, we have our presentational components ready. Now, let's integrate Firebase with our application.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset