点击子组件内链接时关闭父组件Popover的实现方案咨询
推荐实现方案
方案1:Props 透传(优先推荐,适配你当前的组件结构)
你当前的组件层级只有两层(HeaderMenu → Notifications),直接通过props传递关闭函数是成本最低、逻辑最清晰的方案,不需要引入额外的全局状态或监听逻辑。
步骤1:在HeaderMenu中给Notifications组件传递关闭函数
修改HeaderMenu里渲染Notifications的代码:
// HeaderMenu.tsx 中ShowMenu函数内的部分 <ul> {/* 把handleClose作为props传给Notifications */} <Notifications onLinkClick={handleClose} /> </ul>
步骤2:在Notifications组件中接收props并绑定到Link的点击事件
// Notifications.tsx // 组件定义时先接收onLinkClick参数 interface NotificationsProps { onLinkClick?: () => void; } const Notifications = ({onLinkClick}: NotificationsProps) => { // 原有逻辑省略... return ( // 原有结构省略... <Link to={`/profile/${notification.followedUser.id}`} onClick={() => onLinkClick?.()} // 点击时调用父组件传过来的关闭函数,不影响默认跳转逻辑 > {notification.followedUser.user_name} </Link> ) }
方案2:Context 上下文(适合嵌套层级更深的场景)
如果后续你的Notifications组件上层还有更多嵌套组件,不想层层透传props,可以用React内置的Context来共享关闭函数,避免props钻穿问题:
步骤1:在HeaderMenu中创建并提供Context
// HeaderMenu.tsx import { createContext } from 'react'; // 先创建Context const PopoverCloseContext = createContext<(() => void) | undefined>(undefined); const HeaderMenu = () => { // 原有逻辑(handleClose、state等)省略... const ShowMenu = () => { return ( <div className={classes.profile}> <PopoverCloseContext.Provider value={handleClose}> <ul> <Notifications /> </ul> <ul> <li onClick={handleClose}><Link to={`/profile/${currentUserVar().id}`}>Profile</Link></li> <li onClick={handleClose}><Link to='/' onClick={logout}>Logout</Link></li> </ul> </PopoverCloseContext.Provider> </div> ); }; // 原有return逻辑省略... }
步骤2:在Notifications组件中消费Context
// Notifications.tsx import { useContext } from 'react'; import { PopoverCloseContext } from './HeaderMenu'; const Notifications = () => { const handlePopoverClose = useContext(PopoverCloseContext); // 原有逻辑省略... return ( <Link to={`/profile/${notification.followedUser.id}`} onClick={() => handlePopoverClose?.()} > {notification.followedUser.user_name} </Link> ) }
以上两种方案都比你提到的用Reactive variable全局监听的方式更轻量化,逻辑内聚性更高,不会产生多余的全局状态依赖。
内容的提问来源于stack exchange,提问作者Peter Boomsma
相关产品推荐
相关产品推荐

