Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

280
Vistas
React.js how to get an element and paint it a different color

I'm making a cinema app, where I will select seats in cinema hall and add tickets to the cart

Function to display cinema hall:

export default function CinemaHall(props) {
   const row = props.row;
   const seats = props.seats;
   const hall = [];

   const [isActive, setIsActive] = useState(false);

   function getSeats(place) {
       setIsActive(isActive => !isActive);
       console.log("Row: " + row, "Place: " + place);
   }

   for(let i = 1; i < seats; i++) {
       hall.push(
          <div className="seats" onClick={() => getSeats(i)} style={{backgroundColor: isActive ? "rgb(255, 208, 0)" : "rgb(58, 130, 218)"}}></div>
       )
   } 

   return hall;
}

It returns my hall (look at image):

enter image description here

But if I click on the seat, then not one seat is repainted, but a whole row. How to fix it?

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

There are a few things, but the main thing is that you'll need to maintain a separate "active" flag for each seat. For instance, you might have a Set of active seats.

See comments for details and other notes:

export default function CinemaHall({ row, seats }) {
    // Maintain a map of the seats that are "active"
    const [seatsActive, setSeatsActive] = useState(new Set());

    function toggleSeat(place) {
        // Generally, use the callback form when updating state based on
        // existing state
        setSeatsActive((previous) => {
            // Get a new set
            const update = new Set(previous);
            // Toggle this seat: remove it if it's in the set, add it if
            // it isn't
            if (update.has(place)) {
                update.delete(place);
            } else {
                update.add(place);
            }
            console.log(`Row: ${row} Place: ${place} Active: ${update.has(place)}`);
            return update;
        });
    }

    const hall = [];
    // If the first seat is `1`, you want to loop until `<= seats`, not
    // just `< seats`, if you want `seats` number of seats
    for (let seat = 1; seat <= seats; seat++) {
        // Note the `key` prop -- it's important to include that in arrays
        // managed by React. In this case, we can use the seat number, but
        // beware there are many times you can't use an array index as a key!
        // Note using `seatsActive.has(seat)` to see if the seat is "active"
        hall.push(
            <div
                key={seat}
                className="seats"
                onClick={() => toggleSeat(seat)}
                style={{ backgroundColor: seatsActive.has(seat) ? "rgb(255, 208, 0)" : "rgb(58, 130, 218)" }}
            />
            // Note that in JSX (unlike HTML), you can self-close void
            // element tags like `div`
        );
    }

    return hall;
}

Re my note about using seat as the key: It's fine here, but usually using a loop counter is not okay, details in this article linked from the React keys documentation.


Side note: I'd use a class, not inline styling, to indicate active seats:

<div
    // ...
    className={`seat ${seatsActive.has(seat) ? "active" : ""}`}
/>
about 4 years ago · Juan Pablo Isaza Denunciar

0

The main problem is that you have one state for all places. You can do something like this. And in my opinion you have an unnecessary variable like a hall.

const CinemaHall = ({ seats = [1, 2, 3, 4, 5] }) => {

  const [seatsWithStatus, setSeatsWithStatus] = useState(() => {
    return seats.map((seat, idx) => (
      {
        id: idx, // just in case
        seat,
        isActive: false
      }
    )
    )
  });

  const getSeats = (id) => {
    const foundSeat = seatsWithStatus.find(seat => seat.id === id);
    foundSeat.isActive = !foundSeat.isActive;
    setSeatsWithStatus(seatsWithStatus.map(seat => {
      if (seat.id === id) {
        return foundSeat;
      }
      return seat
    }))
  }

  const showSeatsElement = () => (
    seatsWithStatus.map((seat, idx) => (
      <div className="seats"
        key={idx}
        onClick={() => getSeats(seat.id)}
        style={{ backgroundColor: seat.isActive ? "rgb(255, 208, 0)" : "rgb(58, 130, 218)"}}
      ></div>
    ))
  )

  return (
    <>
      {showSeatsElement()}
    </>
  )
}

export default CinemaHall;
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda