Search⌘ K
AI Features

Sharing State - Row & Seat Components

Explore how to manage shared state for seat availability and selection using React hooks and props. Understand the interaction between parent Row and child Seat components to update seat statuses dynamically, improving interactivity and state management in Rails-based front-end development.

We'll cover the following...

The rows in the venue body are the same as before, except we are passing the number of tickets to buy as a new prop in the object.

The Row component has gotten a lot more functionality, some of which has been taken from the Seat component. In this version of the code, the status of a seat depends on the status of the seats next to it—if the tickets to buy number is two, then a set with an already sold seat next to it is not available. Because an individual seat can no longer contain all the data needed to ascertain it’s status, the status for the entire row now needs to be stored in the Row component.

Here’s the Row code:

TypeScript 3.3.4
import * as React from "react"
import Seat from "../components/seat"
interface RowProps {
rowNumber: number
seatsInRow: number
ticketsToBuy: number
}
const Row = (props: RowProps) => {
const [seatStatuses, setSeatStatuses] = React.useState(
Array.from(Array(props.seatsInRow).keys()).map(() => "open")
)
function isSeatValid(seatNumber): boolean {
if (seatNumber + props.ticketsToBuy > props.seatsInRow) {
return false
}
for (let i = 1; i < props.ticketsToBuy; i++) {
if (seatStatuses[seatNumber + i] === "held") {
return false
}
}
return true
}
function validSeatStatus(seatNumber): string {
if (seatStatuses[seatNumber] === "held") {
return "held"
} else {
return isSeatValid(seatNumber) ? "open" : "invalid"
}
}
function newState(oldStatus: string): string {
if (oldStatus === "open") {
return "held"
} else if (oldStatus === "held") {
return "open"
} else {
return "invalid"
}
}
function onSeatChange(seatNumber: number): void {
if (validSeatStatus(seatNumber) === "invalid") {
return
}
setSeatStatuses(
seatStatuses.map((status, index) => {
if (index >= seatNumber && index < seatNumber + props.ticketsToBuy) {
return newState(seatStatuses[seatNumber])
} else {
return status
}
})
)
}
const seatItems = Array.from(Array(props.seatsInRow).keys()).map(
seatNumber => {
return (
<Seat
key={seatNumber}
seatNumber={seatNumber}
status={validSeatStatus(seatNumber)}
clickHandler={onSeatChange}
/>
)
}
)
return <tr>{seatItems}</tr>
}
export default Row

This component does two important things: First, it keeps track of the seat statuses in an array. Second, it defines a ...