0

I am creating my first app in React. It is a cinema booking app. I have component which is a single seat in screening room and a screening room component build with list of seats and reservation. I need access to seat id which user will choose and send this data to api after clicking on submit button. The way I am doing this now doesn't work. I think that because I do not render single seat in screeningRoom component but list.

Here is my code:

Seat component

import React, { Component } from "react";
import "./seat.css";

class Seat extends Component {
  constructor(props) {
    super(props);
    this.state = {
      bgc: this.props.ticket ? "red" : "grey",
      seatId: ""
    };
    //console.log(this.props)
  }
  reserve = () => {
    if (!this.props.ticket) {
      this.state.bgc === "grey"
        ? this.setState({ bgc: "green" })
        : this.setState({ bgc: "grey" });
    }
    this.setState({ seatId: this.props.id });
    //console.log (this.props.id)
  };

  render() {
    return (
      <div>
        <input
          className="seat"
          style={{ backgroundColor: this.state.bgc }}
          onClick={this.reserve}
        ></input>
      </div>
    );
  }
}
export default Seat;

screeningRoom component

import React, { Component } from "react";
import axios from "axios";
import Seat from "./seats";
import "./screeningRoom.css";

export default class screeningRoom extends Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: false,
      seats: [],
      room: [],
      clicked: []
    };
    this.handleClick = this.handleClick.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  async componentDidMount() {
    this.setState({ loading: true });

    const {
      match: { params }
    } = this.props;

    const res = await axios.get(
      `http://localhost:8080/api/shows/${params.id}/seats`
    );
    //console.log(res)

    this.setState({ seats: res.data.seats });
    //console.log(this.state.seats)
    this.setState({ room: res.data.name });
  }
  renderSeats() {
    return this.state.seats.map(seat => (
      <Seat
        onClick={this.handleClick.bind(this)}
        key={seat._id}
        value={seat._id}
        ticket={seat.ticket}
        seat={seat}
      />
    ));
  }

  handleSubmit(e) {
    e.preventDefault();
    console.log(e.target.value);
  }
  handleClick(e) {
    console.log(e.currentTarget.value);
  }

  render() {
    return (
      <div
        className="screening-room d-flex flex-column justify-contnt-center align-items-center"
        style={{ marginTop: 20 }}
      >
        <h3 style={{ color: "white" }}>Room: {this.state.room} </h3>
        <div className="screen">screen</div>
        <form onSubmit={this.handleSubmit.bind(this)}>
          <div className={this.state.room}>{this.renderSeats()}</div>
          <input type="submit" value="Submit" />
        </form>
      </div>
    );
  }
}
1

1 Answer 1

2

You aren't passing the id to the Seat component. So it makes sense why this.props.id is not there.

Either pass the id to the component:

<Seat 
  id={seat._id} 
  onClick={this.handleClick.bind(this)} 
  key={seat._id} 
  value={seat._id} 
  ticket={seat.ticket} 
  seat={seat}
/>

Or change which prop you look for since they are the same:

this.setState({seatId: this.props.value})

Here is a link to the React docs on components and props. This is a very fundamental and important part of React and I would recommend starting here.

Sign up to request clarification or add additional context in comments.

8 Comments

ok but how will I access that id? console does not log anything at the moment on click
Which log are you referring to? You have a function handleClick that gets bound to this twice, but then is never used. So I wouldn't expect that log to fire. In reserve the console log is commented out? I'm assuming you uncommented it? If so, and if you made my suggested change to pass id, it will be there
The console log in the constructor will also fail. You would need to log props, not this.props. And as a side note: you should also change the constructor to this bgc: props.ticket ? "red" : "grey"
click in Seat component works fine. Everything in this component work as it should. My problem is screeningRoom component. In Seat component user click on seat item and it changes color to green (as reserved). Then I want in screeningRoom component get chosen seat id from API and post it with submit button.
Thank you so much Brian! "prevState" is exactly what I needed and did not know since now:)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.