Sharing State - Row & Seat Components
Read about how to share state in the row component in this lesson.
We'll cover the following...
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:
//START:P1import * as React from "react"import Seat from "components/seat"interface RowProps {rowNumber: numberseatsPerRow: numberticketsToBuyCount: 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:P2return "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 (<Seatkey={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 ...