如何在点击页面其他区域时折叠React MUI Accordion组件
实现MUI Accordion点击外部区域自动折叠
纯CSS无法实现点击页面其他区域折叠Accordion的需求,因为CSS没有能力监听全局点击事件并判断点击位置。这里提供结合React状态管理和事件监听的解决方案:
步骤说明
- 使用
useState管理Accordion的展开/折叠状态 - 通过
useRef获取Accordion的DOM元素,用于判断点击区域是否在组件内部 - 监听
document的点击事件,当点击区域不在Accordion内时,将状态设为折叠
完整代码示例
import { useState, useEffect, useRef } from 'react'; import { Accordion, AccordionSummary, AccordionDetails, TextField, Typography, ExpandMoreIcon } from '@mui/material'; function YourComponent() { const [entity, setEntity] = useState({ entityName: '' }); const [expanded, setExpanded] = useState(false); const accordionRef = useRef(null); // 监听全局点击事件 useEffect(() => { const handleClickOutside = (event) => { if (accordionRef.current && !accordionRef.current.contains(event.target)) { setExpanded(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, []); return ( <Accordion ref={accordionRef} expanded={expanded} onChange={() => setExpanded(!expanded)} > <AccordionSummary focusVisibleClassName='focus' expandIcon={<ExpandMoreIcon />} aria-controls="panel1a-content" id="panel1a-header" > <TextField style={{ width: 350 }} id="entityName" value={entity.entityName} onChange={(event) => { setEntity({ ...entity, entityName: event.target.value }); }} /> </AccordionSummary> <AccordionDetails sx={{ borderTop: '1px dashed black', width: 400 }}> <Typography> Source </Typography> <TextField sx={{ width: 350 }}></TextField> <Typography> Classification </Typography> <TextField sx={{ width: 350 }}></TextField> </AccordionDetails> </Accordion> ); } export default YourComponent;
关键点解释
accordionRef:获取Accordion的DOM节点,用于判断点击事件的目标是否在组件内部handleClickOutside:全局点击事件处理函数,当点击区域不在Accordion内时,将expanded设为falseuseEffect:在组件挂载时添加全局监听,卸载时移除,避免内存泄漏Accordion的expanded属性:绑定状态,控制组件的展开/折叠
你的原有focus CSS样式可以继续保留,不会影响这个功能。
内容的提问来源于stack exchange,提问作者karkiekie
相关产品推荐
相关产品推荐

