Jia*_*827 5 sass reactjs material-ui
我在导航栏中有一个使用 material-ui/core 构建的导航菜单。
我使用 useRef 来跟踪切换菜单关闭时单击按钮的位置。
anchorRef.current.contains(event.target)
我得到'Uncaught TypeError: anchorRef.current.contains is not a function'.
我尝试了 'Object.values(anchorRef.current).includes(event.target)',它总是返回 false。
- 更新 -
anchorRef.current.props 对象。
withStyles {
props:{
aria-haspopup: "true"
aria-owns: undefined
children: "??"
className: "nav-menu--btn"
onClic: f onClick()
get ref: f()
isReactWarning: true
arguments: (...)
caller: (...)
length: 0
name: "warnAboutAccessingRef"
...
}, context{...}, refs{...}, ...}
Run Code Online (Sandbox Code Playgroud)
const ToggleMenuList = ({ navAdminList, navAdminItems, classes }) => {
const [activeId, setActiveId] = useState(null);
const anchorRef = useRef(null);
const handleToggle = id => {
setActiveId(id);
};
const handleClose = event => {
if (anchorRef.current && anchorRef.current.contains(event.target)) {
return;
}
setActiveId(null);
};
return (
<React.Fragment>
<div className={`nav-menu--admin ${classes.root}`}>
{navAdminList.map(e => (
<div key={e.id}>
<Button
ref={anchorRef}
aria-owns={activeId === e.id ? 'menu-list-grow' : undefined}
aria-haspopup="true"
onClick={() => handleToggle(e.id)}
>
{e.name}
</Button>
{activeId === e.id && (
<ToggleMenuItems
id={e.id}
activeId={activeId}
handleClose={handleClose}
anchorRef={anchorRef}
items={navAdminItems[e.id]}
/>
)}
</div>
))}
</div>
</React.Fragment>
);
};
export default withStyles(styles)(ToggleMenuList);
Run Code Online (Sandbox Code Playgroud)
const ToggleMenuItems = ({
listId,
activeId,
handleClose,
anchorRef,
items,
}) => {
const isOpen = activeId === listId;
const leftSideMenu = activeId === 3 || activeId === 4 ? 'leftSideMenu' : '';
return (
<Popper
open={isOpen}
anchorEl={anchorRef.current}
keepMounted
transition
disablePortal
>
{({ TransitionProps, placement }) => (
<Grow
{...TransitionProps}
style={{
transformOrigin:
placement === 'bottom' ? 'center top' : 'center bottom',
}}
className={`toggle-menu ${leftSideMenu}`}
>
<Paper id="menu-list-grow">
<ClickAwayListener
onClickAway={handleClose}
>
<MenuList className="toggle-menu--list">
{items.map(e => (
<MenuItem
key={e.id}
className="toggle-menu--item"
onClick={handleClose}
>
<Link
to={e.to}
className="anchor td-none c-text1 toggle-menu--link"
>
{e.name}
</Link>
</MenuItem>
))}
</MenuList>
</ClickAwayListener>
</Paper>
</Grow>
)}
</Popper>
);
};
export default ToggleMenuItems;
Run Code Online (Sandbox Code Playgroud)
react: ^16.8.6
react-dom: ^16.8.6
react-router-dom: ^4.3.1
@material-ui/core: ^3.1.2
Run Code Online (Sandbox Code Playgroud)
我假设您在单击外部某处时ToggleMenuItems设置了全局(document-level?)事件侦听器以折叠菜单。
并且您有一个同级按钮元素。单击您想要保持菜单展开,对吗?因此,这就是使用.containsinonClick来检查我们是否在特定 范围之外ToggleMenuItems但在特定 范围内被点击的点Button。它不起作用的原因:<Button>是自定义的基于类的 React 组件,因此它在 ref 中返回 React 组件实例。而且它没有任何特定于 DOM 的方法,例如.contains
您可以修改当前的方法:如果Button已单击,则停止冒泡事件。它将停止设置的全局事件处理程序ToggleMenuItems进行反应。
const stopPropagation = (event) => event.stopPropagation();
const ToggleMenuList = ({ navAdminList, navAdminItems, classes }) => {
const [activeId, setActiveId] = useState(null);
const anchorRef = useRef(null);
const handleToggle = id => {
setActiveId(id);
};
const handleClose = event => {
setActiveId(null);
};
return (
<React.Fragment>
<div className={`nav-menu--admin ${classes.root}`}>
{navAdminList.map(e => (
<div key={e.id}>
<div onClick={stopPropagation}>
<Button
aria-owns={activeId === e.id ? 'menu-list-grow' : undefined}
aria-haspopup="true"
onClick={() => handleToggle(e.id)}
>
{e.name}
</Button>
</div>
{activeId === e.id && (
<ToggleMenuItems
id={e.id}
activeId={activeId}
handleClose={handleClose}
anchorRef={anchorRef}
items={navAdminItems[e.id]}
/>
)}
</div>
))}
</div>
</React.Fragment>
);
};
export default withStyles(styles)(ToggleMenuList);
Run Code Online (Sandbox Code Playgroud)
我已将stopPropagation处理程序放在外面,因为它不依赖于任何内部变量。
| 归档时间: |
|
| 查看次数: |
5288 次 |
| 最近记录: |