React+NextJS:点击角色图标让模态框展示对应角色详情
问题:点击角色图标后模态框展示所有角色信息,需改为仅展示对应角色详情
我是React新手,用NextJS开发。现在有个角色数组,用map渲染每个角色的名称和描述。想实现点击角色图标时,模态框只显示该角色的职责和要求,但现在模态框会把所有角色的内容都展示出来,不知道怎么定位特定角色的属性,求帮助。
角色数组示例
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", }, ]
核心问题分析
当前代码的问题很明确:
- 模态框内直接遍历所有角色,没有区分当前点击的目标角色
- 自定义
useModal仅管理了模态框的开关状态,没有存储选中角色的信息
解决方案:分步修改代码
1. 升级useModal Hook,支持存储选中角色
修改Hook,新增状态保存选中角色,拆分开关方法以便传入角色参数:
import { useState } from 'react'; // 若有角色类型定义可引入,无则省略 // import { Role } from './your-types'; export default function useModal() { const [isOpen, setIsOpen] = useState(false); const [selectedRole, setSelectedRole] = useState<Role | null>(null); // 打开模态框并传入选中角色 const open = (role: Role) => { setSelectedRole(role); setIsOpen(true); }; // 关闭模态框并清空选中角色 const close = () => { setIsOpen(false); setSelectedRole(null); }; return { isOpen, selectedRole, open, close }; }
2. 修改Careers页面组件,传递选中角色到模态框
更新点击事件逻辑,调用open方法传入当前角色,同时模态框仅渲染选中角色的信息:
export default function Careers() { const { isOpen, selectedRole, open, close } = 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"> {/* 点击时传递当前角色给open方法 */} <span onClick={() => open(role)}> <Image src={roleIcon} className="h-6 w-6 text-white" alt={role.name} 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={close} > {/* 仅渲染选中的角色信息 */} {selectedRole && ( <div className="glass relative pl-16"> <dt className="text-base m-2 font-semibold leading-7 text-gray-900"> {selectedRole.name} </dt> <dd className="mt-2 mr-2 mb-2 text-base leading-7 text-gray-600"> <strong>职责:</strong>{selectedRole.responsibilities} </dd> <dd className="mt-2 mr-2 mb-2 text-base leading-7 text-gray-600"> <strong>要求:</strong>{selectedRole.requirements} </dd> </div> )} </TestModal> </div> </> ) }
3. (可选)更新Modal组件类型定义
如果需要更严谨的类型检查,可更新Modal的props类型(不修改也不影响运行):
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> )} </> ); }
关键改动说明
- 在
useModal中新增selectedRole状态,专门存储当前点击的角色对象 - 将原
toggle拆分为open(接收角色参数)和close方法,分别处理打开/关闭逻辑 - 页面点击角色图标时,调用
open(role)将当前角色传入Hook - 模态框内不再遍历所有角色,而是根据
selectedRole渲染对应内容
修改完成后,点击不同角色的图标,模态框就会只显示该角色的职责和要求了。
内容的提问来源于stack exchange,提问作者liitepiixels
相关产品推荐
相关产品推荐

