Reputation: 421
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:
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:
Having the menu code in the loop
Having the menu code outside of the loop
Opening the menu around the cursor's X,Y coordinates
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
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