React表格map渲染时点击三点菜单仅显示对应行下拉的解决方案
问题原因
所有行的下拉菜单显隐都绑定了同一个布尔类型状态openDropdown,只要这个状态变为true,map遍历渲染的每一行都会满足下拉菜单的渲染条件,自然会出现所有菜单同时弹出的问题,无法区分当前点击的具体行。
修复方法
- 把原来存储布尔值的
openDropdown状态,替换为存储当前展开菜单的行唯一ID的状态,初始值设为null,代表默认没有菜单展开
// 替换原有状态定义 // const [openDropdown, setOpenDropdown] = useState(false); const [activeRowId, setActiveRowId] = useState(null);
- 修改三点按钮的点击逻辑:如果当前点击的行已经是激活状态,就把状态设为
null关闭菜单;否则把状态设为当前点击行的ID,仅展开当前行的菜单 - 修改下拉菜单的渲染判断:只有当前遍历行的ID和状态中存储的激活ID一致时,才渲染对应行的下拉菜单
修复后完整渲染代码
{ClientsData.map((u, index) => ( <tr id={`element-${index}`} className={u.checked ? 'user active' : 'user'} key={u.id}> <td className="input-check"> <input type="checkbox" className="checkbox" /> </td> <td>{u.email}</td> <td>{u.societe}</td> <td>{u.matriculeFiscale}</td> <td>{u.categorie}</td> <td>{u.reglement}</td> <td className={u.statut === 'Bloqué' ? 'user-status' : 'user-status activé'}> {u.statut} </td> <td className="last-user-element"> <Link to={`/admin/users/user_details/${u.id}`} className="link-user"> <icons.BsEye className="see-user" /> </Link> <div className="contain"> <icons.BsThreeDotsVertical onClick={() => { // 点击同一行按钮则关闭菜单,否则打开当前行菜单 setActiveRowId(activeRowId === u.id ? null : u.id); setIndice(u.id); setIndexUser(index); }} className="user-option" key={u.id} /> {/* 仅当前行ID匹配激活状态时渲染下拉菜单 */} {activeRowId === u.id && <UsersModalOptions />} </div> </td> </tr> ))}
可选优化
如果需要实现点击页面其他区域自动关闭下拉菜单的效果,可以给菜单外层的contain容器绑定ref,在组件挂载时添加全局点击监听,判断点击目标不在容器范围内时,执行setActiveRowId(null)即可。
内容的提问来源于stack exchange,提问作者Ronice Yemeli
相关产品推荐
相关产品推荐

