React+styled-components项目监听ESC键关闭Drawer模态框实现咨询
实现ESC键关闭抽屉的方案
核心实现逻辑
- 在Drawer组件内部监听键盘事件,逻辑内聚不污染父组件
- 仅在抽屉打开时绑定事件监听,减少不必要的性能消耗
- 组件卸载/抽屉关闭时自动移除监听,避免内存泄漏
具体代码修改
修改Drawer组件代码
import React, { useEffect } from "react"; import styled from "styled-components"; type Props = { isOpen: boolean; padding?: number; children: React.ReactNode; onClose: () => void; }; export default (props: Props) => { // 新增ESC键监听逻辑 useEffect(() => { if (!props.isOpen) return; const handleEscPress = (e: KeyboardEvent) => { if (e.key === 'Escape') { props.onClose(); } }; window.addEventListener('keydown', handleEscPress); return () => window.removeEventListener('keydown', handleEscPress); }, [props.isOpen, props.onClose]); return ( <> <Overlay isOpen={props.isOpen} onClick={props.onClose} /> <DrawerModal {...props}>{props.children}</DrawerModal> </> ); }; const DrawerModal = styled.div<Props>` position: absolute; overflow: scroll; top: 0; right: 0; height: 100vh; width: ${({ isOpen }: Props) => (isOpen ? 400 : 0)}px; background: blue; box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.25); transition: 200ms cubic-bezier(0.25, 0.1, 0.24, 1); `; const Overlay = styled.div<{ isOpen: boolean }>` position: absolute; top: 0; left: 0; right: 0; bottom: 0; z-index: ${(props: { isOpen: boolean }) => (props.isOpen ? 0 : -1)}; `;
App组件无需修改
原有App代码可以直接保留使用,所有关闭逻辑已经封装在Drawer组件内部,不影响原有调用方式。
补充说明
这里使用e.key === 'Escape'判断而不是废弃的keyCode属性,符合最新的Web标准,兼容性覆盖所有主流现代浏览器。如果需要兼容非常老旧的浏览器,可以补充e.keyCode === 27的判断条件。
内容的提问来源于stack exchange,提问作者user15375616
相关产品推荐
相关产品推荐

