How to target a single map()'d element in React?

TL;DR - I need to target and open a single menu from a bunch that are created by map()'ing an array, without a reference.

I have a problem with my React.js code that I can't quite get my head around and could do with another set of eyes, please.

The basic premise of this logic is for a user to be able to pick tasks that need carrying out in rooms of a building. The building can be from a number of sectors and as such can have a number of different rooms, each with their own tasks. In short, it needs to be dynamic.

This is simplified overview of my data structure:

When a user clicks a Property type, it has a sector associated with it. Upon selection, the RoomGroups are rendered by passing the roomGroup array in to a map().

This is a basic example of the code used for this (minus the CSS for clarity)...

const renderRoomGroups = () => {
    return (
        <div className={'requirementsInfoComponent-addRoom-row-container'}>
            {data_roomGroups.map(roomGroup => {
                return (
                    <div key={roomGroup.id}>

                        <div onClick={() => handleRoomGroupSelection(roomGroup)}>
                            {/* Icon */}
                            <MdAddCircle />

                            {/* Room name */}
                            <p>{roomGroup.group_name}</p>
                        </div>

                        {isRoomGroupMenuVisible &&
                            <div>
                                {renderRoomsMenu()}
                            </div>}

                    </div>
                )
            })}
        </div>
    )
}

const handleRoomGroupSelection = (roomGroup) => {
    setRoomGroupSelection(roomGroup);
    setIsRoomGroupMenuVisible(true);
}

const renderRoomsMenu = () => {

    const roomsByGroup = data_rooms.filter(room => room.room_group_id === roomGroupSelection.id);

    return (
        <ModalContainer>
            {roomsByGroup.map(room => {
                return (
                    <div key={room.id}>
                        <p>{room.room_name}</p>
                    </div>
                )
            })}
        </ModalContainer>
    )
}

...which produces the following UI:

Room Groups picker

The problem is, when the user clicks on a RoomGroup it should open the relevant Room's menu for them to be able to choose a room, but as the menu is within the map function it opens all the menus at the same time. I can move the menu out of the map, but then it always opens in the same place and not in the related section which is bad for UX.

So, I would like a way to only open the menu which is relevant to the selected RoomGroup, in the section it belongs to.

I've had a look around and have seen some similar questions, but these have hard coded menus that need to open dynamically which I can do, but it's not a very good option given the amount of differing data.

I've tried:

I thought about making each menu its own component and passing it its own onClick() function, but how would I target a single menu?

Upvotes: 0

Views: 1418

Answers (1)

Domino987
Domino987

Reputation: 8774

You need to show the menu only for the correct room. Try this:

 {roomGroup.id === roomGroupSelection.id &&
           <div>
               {renderRoomsMenu()}
           </div>
}

To only render the menu where you need it. And you could also remove the isRoomGroupMenuVisible

Upvotes: 1

Related Questions