MUI Swipeable Drawer高度调整时卡顿问题求助
MUI Swipeable Drawer 视图高度变化卡顿至底部的问题修复方案
问题说明
MUI的Swipeable Drawer存在异常:当视图高度变化时(比如调整窗口大小、切换响应式预览),抽屉会卡顿到底部位置。这个问题在iOS Safari新版本中尤其突出——浏览器底部搜索栏滚动隐藏时,会频繁触发视口高度变化,导致抽屉反复卡顿。
当前代码中,通过Global组件给抽屉设置了高度样式:
<Global styles={{ '.MuiDrawer-root > .MuiPaper-root': { height: `calc(50% - ${drawerBleeding}px)`, overflow: 'visible', }, }} />
如果注释掉上述代码里的height属性,抽屉功能会恢复正常,但会出现新问题:页面刷新后抽屉直接消失,必须点击开关按钮打开再关闭才能正常显示。
修复思路与代码示例
1. 动态监听视口变化,实时更新抽屉高度
不再依赖静态样式计算,而是监听窗口尺寸变化(包括iOS的视口调整),实时更新抽屉高度,避免样式不匹配导致的卡顿:
import { useEffect, useState } from 'react'; import { SwipeableDrawer, Global } from '@mui/material'; const CustomSwipeableDrawer = ({ open, onClose, onOpen }) => { const drawerBleeding = 16; // 根据业务配置调整该值 const [drawerHeight, setDrawerHeight] = useState(`calc(50% - ${drawerBleeding}px)`); useEffect(() => { const updateDrawerHeight = () => { // 重新计算高度,适配当前视口 setDrawerHeight(`calc(50% - ${drawerBleeding}px)`); }; // 监听窗口 resize 和 设备旋转事件 window.addEventListener('resize', updateDrawerHeight); window.addEventListener('orientationchange', updateDrawerHeight); // 组件卸载时移除监听 return () => { window.removeEventListener('resize', updateDrawerHeight); window.removeEventListener('orientationchange', updateDrawerHeight); }; }, [drawerBleeding]); return ( <> <Global styles={{ '.MuiDrawer-root > .MuiPaper-root': { height: drawerHeight, overflow: 'visible', }, }} /> <SwipeableDrawer open={open} onClose={onClose} onOpen={onOpen} {/* 其他抽屉配置属性 */} > {/* 抽屉内容区域 */} </SwipeableDrawer> </> ); };
2. 使用自定义类名替代全局样式覆盖
直接修改MUI默认类名容易引发样式冲突,建议给抽屉的Paper组件添加自定义类名,精准控制样式:
<SwipeableDrawer PaperProps={{ className: 'custom-drawer-paper', }} open={open} onClose={onClose} onOpen={onOpen} > {/* 抽屉内容 */} </SwipeableDrawer> <Global styles={{ '.custom-drawer-paper': { height: drawerHeight, overflow: 'visible', }, }} />
3. 解决刷新后抽屉消失的问题
确保抽屉的open状态在组件初始化时正确设置,比如根据业务需求设置初始值,或者从本地存储读取状态:
// 示例:初始状态设为打开,或根据业务逻辑调整 const [open, setOpen] = useState(true);
也可以在组件挂载时,强制触发一次状态更新或重绘,确保DOM渲染正常。
内容的提问来源于stack exchange,提问作者Alex-Pober
相关产品推荐
相关产品推荐

