点击IconButton触发状态更新后出现无限循环问题求助
问题描述
使用MUI框架实现图标按钮触发菜单弹窗,复制官方示例代码测试,但点击IconButton时UI冻结,同时Firebase的onAuthStateChanged函数无限循环执行。
相关代码如下:
组件JSX代码
<div> <IconButton onClick={handleOpenMenu} aria-controls={open ? 'basic-menu' : undefined} aria-haspopup="true" aria-expanded={open ? 'true' : undefined} > <MoreVertIcon /> </IconButton> <Menu id="demo-positioned-menu" aria-labelledby="demo-positioned-button" anchorEl={anchorEl} open={open} onClose={handleMenuClose} anchorOrigin={{ vertical: 'top', horizontal: 'left', }} transformOrigin={{ vertical: 'top', horizontal: 'left', }} > <MenuItem onClick={handleMenuClose}>Profile</MenuItem> <MenuItem onClick={handleMenuClose}>My account</MenuItem> <MenuItem onClick={handleMenuClose}>Logout</MenuItem> </Menu> </div>
事件处理函数
const [anchorEl, setAnchorEl] = useState(null); const open = Boolean(anchorEl); const handleOpenMenu = (event) => { setAnchorEl(event.currentTarget); }; const handleMenuClose = () => { setAnchorEl(null); };
Firebase认证监听代码
var unsubscribe = onAuthStateChanged(auth, (user) => { if (user) { const uid = user.uid; console.log(uid) setAuthenticated(true) } else { setAuthenticated(false) } });
问题原因与解决方法
核心原因
onAuthStateChanged直接写在组件函数内部,会在每次组件渲染时重新创建订阅:
- 初始渲染时订阅认证状态变化,触发
setAuthenticated更新状态,导致组件重渲染; - 重渲染时又会再次执行
onAuthStateChanged创建新订阅,再次触发setAuthenticated,形成无限循环; - 点击IconButton时调用
setAnchorEl触发组件重渲染,进一步加剧循环,最终导致UI冻结。
解决步骤
用React的useEffect钩子包裹认证监听逻辑,确保只在组件挂载时订阅一次,并且在组件卸载时清理订阅:
import { useEffect } from 'react'; // ...其他组件代码 useEffect(() => { const unsubscribe = onAuthStateChanged(auth, (user) => { if (user) { const uid = user.uid; console.log(uid); setAuthenticated(true); } else { setAuthenticated(false); } }); // 组件卸载时取消订阅,避免内存泄漏 return unsubscribe; }, []); // 空依赖数组表示仅在组件挂载/卸载时执行
额外优化点
当前代码中IconButton的aria-controls属性值是basic-menu,但Menu的id是demo-positioned-menu,两者不匹配,可能导致无障碍访问问题,建议修正为一致:
<IconButton onClick={handleOpenMenu} aria-controls={open ? 'demo-positioned-menu' : undefined} aria-haspopup="true" aria-expanded={open ? 'true' : undefined} >
内容的提问来源于stack exchange,提问作者Bucky
相关产品推荐
相关产品推荐

