Search code examples
javascriptreactjsreact-context

Context API isn't returning the id of clicked element


I'm building a React app in which a user choses how many tickets they want and then selects their seats from a layout.

I'm using the context API which is working for various elements but I'm trying to return the id of seats the user chooses.

This is the component with the clickable elements I need to get the IDs from -

class ChooseSeats extends React.Component {
    render(){
        return(<Context.Consumer>
            {(context) => {
                return (
                    <div>
                        <p>Remaining tickets: {context.state.remainingSeats}</p>
                        <p>Chosen seat: {context.state.chosenSeat}</p>

                        <div>
                        <div id="A1" onClick={context.chooseSeats}>
                            <img src={freeSeat} alt="freeSeat"/>
                        </div>
                        <div id="A2" onClick={context.chooseSeats}>
                            <img src={freeSeat} alt="freeSeat"/>
                        </div>
                        <div id="A3" onClick={context.chooseSeats}>
                            <img src={freeSeat} alt="freeSeat"/>
                        </div>
                        </div>
                    </div>  
                
                )}
            }
        </Context.Consumer>
        )
    }
}

And this is the context file -

export class Provider extends React.Component {
    state = {
        chosenSeat: " ",
        remainingSeats: 8
    }

    render() {
        const { remainingSeats, chosenSeat } = this.state
        
        return(
            <Context.Provider value={{
                state: this.state,
                chooseSeats: (event) => {
                    this.setState({
                        chosenSeat: event.target.id,
                        remainingSeats: remainingSeats - 1
                    })
                    console.log(chosenSeat)
                },
            }}>
                {this.props.children}
            </Context.Provider>
        )
    }
}

In my actual app, the remainingSeats value is originally taken from some dropdown menus in which the user choses their tickets but for simplicity's sake I've just given it a default value of 8 in this case.

The choseSeats function is running because the remainingSeats value reduces by 1 each time a seat is clicked but it doesn't return the id of chosenSeat. I've tried chosenSeat as a string and an array and neither returns anything.

Can anyone tell me where I'm going wrong?


Solution

  • It's because the event.target.id is an empty string. Although you attached the onClick on the div (which should be a button to make it accessible), if you click on the child img, the event.target is the img.

    You can use event.currentTarget - it refers to the element to which the event handler has been attached (div) - or you can create inline functions instead and pass the ids.

    So, instead of

    <div id="A3" onClick={context.chooseSeats}><img ...
    

    you can use

    <button onClick={() => context.chooseSeats('A3')}><img ...
    

    And update your chooseSeats, which receives an ID now, not the event:

    chooseSeats: (id) => {
      this.setState({
        chosenSeat: id,
        remainingSeats: remainingSeats - 1,
      })
      console.log(chosenSeat)
    },