...

/

Sharing State - Row & Seat Components

Sharing State - Row & Seat Components

Read about how to share state in the row component in this lesson.

Row Component

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 two tickets are bought, then a set with an already sold seat to its right is not available. Because an individual seat can no longer contain all the data needed to ascertain its status, the status for the entire row needs to be stored in the Row component.

Here’s the Row code:

Press + to interact
//START:P1
import * as React from "react"
import Seat from "components/seat"
interface RowProps {
rowNumber: number
seatsPerRow: number
ticketsToBuyCount: number
}
const Row = (props: RowProps): React.ReactElement => {
const [seatStatuses, setSeatStatuses] = React.useState(
Array.from(Array(props.seatsPerRow).keys()).map(() => "unsold")
)
function isSeatValid(seatNumber): boolean {
if (seatNumber + props.ticketsToBuyCount > props.seatsPerRow) {
return false
}
for (let i = 1; i < props.ticketsToBuyCount; i++) {
if (seatStatuses[seatNumber + i] === "held") {
return false
}
}
return true
}
function validSeatStatus(seatNumber): string {
if (seatStatuses[seatNumber] === "held") {
return "held"
} else {
return isSeatValid(seatNumber) ? "unsold" : "invalid"
}
}
function newState(oldStatus: string): string {
if (oldStatus === "unsold") {
return "held"
} else if (oldStatus === "held") {
return "unsold"
} else {
//END:P1
//START:P2
return "invalid"
}
}
function onSeatChange(seatNumber: number): void {
if (validSeatStatus(seatNumber) === "invalid") {
return
}
setSeatStatuses(
seatStatuses.map((status, index) => {
if (
index >= seatNumber &&
index < seatNumber + props.ticketsToBuyCount
) {
return newState(seatStatuses[seatNumber])
} else {
return status
}
})
)
}
const seatItems = Array.from(Array(props.seatsPerRow).keys()).map(
(seatNumber) => {
return (
<Seat
key={seatNumber}
seatNumber={seatNumber}
status={validSeatStatus(seatNumber)}
clickHandler={onSeatChange}
/>
)
}
)
return <tr className="h-20">{seatItems}</tr>
}
export default Row
//END:P2

This component keeps track of the seat statuses in an array and defines a click handler to be executed when a seat is clicked. To make that work, the Row component passes that handler function as a prop to the Seat component, namely ...