I'm fairly new to React and I'm using NextJS. I have an array with role objects. I'm mapping over the array to display role name and description. What I'm trying to do is display the other array object properties when user clicks on the role icon. The first map function is able to display each role and description on the page. However, when I click on the role icon, the map function on my modal displays the additional object properties all at once. Is there a way to make it so each icon click shows the specific role properties for that object?
Here is an example of the array:
const roles = [
{
id: 1,
name: 'First Role',
description: 'ipsum description',
responsibilities: 'ipsum responsibilities',
requirements: "ipsum requirement",
},
{
id: 2,
name: 'Fourth Role',
description: 'ipsum description',
responsibilities: 'ipsum responsibilities',
requirements: "ipsum requirement",
},
{
id: 3,
name: 'Third Role',
description: 'ipsum description',
responsibilities: 'ipsum responsibilities',
requirements: "ipsum requirement",
},
This is the current page layout:
export default function Careers() {
const { isOpen, toggle } = useModal()
return (
<>
<Head>
<title>Careers</title>
<meta name='description' content='Careers' />
</Head>
<HeroGeneric heading='Careers' message="" />
<div className=" py-24 sm:py-32">
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div className="mx-auto max-w-2xl lg:text-center">
<h2 className="text-base font-semibold leading-7 text-indigo-600">Open Roles</h2>
<p className="mt-2 text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl">
How you can make a difference
</p>
<p className="mt-6 text-lg leading-8 text-gray-600">
Quis tellus eget adipiscing convallis sit sit eget aliquet quis. Suspendisse eget egestas a elementum
pulvinar et feugiat blandit at. In mi viverra elit nunc.
</p>
</div>
<div className="mx-auto mt-16 max-w-2xl sm:mt-20 lg:mt-24 lg:max-w-4xl">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-10 lg:max-w-none lg:grid-cols-2 lg:gap-y-16">
{roles.map((role) => (
<div key={role.id} className=" glass relative pl-16">
<dt className="text-base m-2 font-semibold leading-7 text-gray-900">
<div className="absolute left-0 top-0 ml-2 mt-2 flex h-10 w-10 items-center justify-center rounded-lg bg-taublue">
<span isOpen={isOpen} onClick={toggle}>
<Image
src={roleIcon}
className="h-6 w-6 text-white"
alt={role.id}
height={"24"} width={"24"}
/>
</span>
</div>
{role.name}
</dt>
<dd className="mt-2 mr-2 mb-2 text-base leading-7 text-gray-600">{role.description}</dd>
</div>
))}
</dl>
</div>
</div>
<TestModal
isOpen={isOpen}
toggle={toggle}
>
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-10 lg:max-w-none lg:grid-cols-2 lg:gap-y-16">
{roles.map((role) => (
<div key={role.id} className=" glass relative pl-16">
<dt className="text-base m-2 font-semibold leading-7 text-gray-900">
{role.name}
</dt>
<dd className="mt-2 mr-2 mb-2 text-base leading-7 text-gray-600">{role.responsibilities}</dd>
<dd className="mt-2 mr-2 mb-2 text-base leading-7 text-gray-600">{role.requirements}</dd>
</div>
))}
</dl>
</TestModal>
</div>
</>
)
}
I'm using this component for my modal:
import React, { ReactNode } from 'react';
interface ModalType {
children?: ReactNode;
isOpen: boolean;
toggle: () => void;
}
export default function Modal(props: ModalType) {
return (
<>
{props.isOpen && (
<div className='modal-overlay' onClick={props.toggle}>
<div onClick={(e) => e.stopPropagation()} className='modal-box'>
{props.children}
</div>
</div>
)}
</>
);
}
And this is the hook I have to open my modal:
export default function useModal() {
const [isOpen, setisOpen] = useState(false);
const toggle = () => {
setisOpen(!isOpen);
};
return {
isOpen,
toggle
};
}
When I click on a specific role icon, the modal should display that roles requirements and responsibilities. However, it currently shows all the objects properties. I've tried to target specific role properties, but I haven't the faintest clue how to do so. I am a new web developer and would appreciate any help with this!
You can create a state to save the role id and show this role in the modal.
Example:
export default function Careers() {
const { isOpen, toggle } = useModal()
const [roleId, setRoleId } = useState('')
const handleClick = (roleId) => {
setRoleId(roleId)
toggle()
}
return (
<>
<Head>
<title>Careers</title>
<meta name='description' content='Careers' />
</Head>
<HeroGeneric heading='Careers' message="" />
<div className=" py-24 sm:py-32">
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div className="mx-auto max-w-2xl lg:text-center">
<h2 className="text-base font-semibold leading-7 text-indigo-600">Open Roles</h2>
<p className="mt-2 text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl">
How you can make a difference
</p>
<p className="mt-6 text-lg leading-8 text-gray-600">
Quis tellus eget adipiscing convallis sit sit eget aliquet quis. Suspendisse eget egestas a elementum
pulvinar et feugiat blandit at. In mi viverra elit nunc.
</p>
</div>
<div className="mx-auto mt-16 max-w-2xl sm:mt-20 lg:mt-24 lg:max-w-4xl">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-10 lg:max-w-none lg:grid-cols-2 lg:gap-y-16">
{roles.map((role) => (
<div key={role.id} className=" glass relative pl-16">
<dt className="text-base m-2 font-semibold leading-7 text-gray-900">
<div className="absolute left-0 top-0 ml-2 mt-2 flex h-10 w-10 items-center justify-center rounded-lg bg-taublue">
<span isOpen={isOpen} onClick={() => handleClick(role.id)}>
<Image
src={roleIcon}
className="h-6 w-6 text-white"
alt={role.id}
height={"24"} width={"24"}
/>
</span>
</div>
{role.name}
</dt>
<dd className="mt-2 mr-2 mb-2 text-base leading-7 text-gray-600">{role.description}</dd>
</div>
))}
</dl>
</div>
</div>
<TestModal
isOpen={isOpen}
toggle={toggle}
>
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-10 lg:max-w-none lg:grid-cols-2 lg:gap-y-16">
<div className=" glass relative pl-16">
<dt className="text-base m-2 font-semibold leading-7 text-gray-900">
{roles[roleId].name}
</dt>
<dd className="mt-2 mr-2 mb-2 text-base leading-7 text-gray-600">{roles[roleId].responsibilities}</dd>
<dd className="mt-2 mr-2 mb-2 text-base leading-7 text-gray-600">{roles[roleId].requirements}</dd>
</div>
</dl>
</TestModal>
</div>
</>
)}