React应用登出时触发Maximum call stack size exceeded问题求助
问题原因
Header组件中维护了本地状态openRightDrawer,并通过useEffect与父组件传入的props.openRightDrawer同步,这种冗余的状态同步逻辑容易引发循环更新:当子组件调用toggleClose触发父组件更新状态后,useEffect会再次更新本地状态,若父组件状态更新又触发Header重新渲染,就会形成无限循环,最终导致栈溢出。此外,若父组件的toggleDrawer函数逻辑错误(比如忽略传入参数,仅做状态切换),会进一步加剧该问题。
解决方案
方案1:移除Header的本地状态,直接使用父组件props控制Drawer
去掉Header中多余的本地状态和同步逻辑,直接用父组件传入的props.openRightDrawer控制Drawer的显示,彻底避免状态同步带来的循环:
修改Header.js代码:
// 移除以下本地状态和同步逻辑 // const [openRightDrawer, setOpenRightDrawer] = useState(props.openRightDrawer); // useEffect(() => { // console.log('called on chat transcript:', props.openRightDrawer); // setOpenRightDrawer(props.openRightDrawer); // }, [props.openRightDrawer]); // ... 保留其他原有代码 // 将Drawer的open属性改为直接使用props值 <Drawer className='mobile-hide-drawer' anchor="left" open={props.openRightDrawer} BackdropProps={{ onClick: handleBackdropClick }} PaperProps={{ style: { background: '#8b1d41', width: '300px', paddingTop: '10px', paddingBottom: '10px', paddingLeft: '5px', paddingRight: '5px' } }} ModalProps={{ BackdropProps: { clickable: false, }, }} onClose={toggleClose} > {drawerContent} </Drawer>
方案2:检查并修正父组件的toggleDrawer函数逻辑
确保父组件中的toggleDrawer是直接将状态设置为传入的参数,而非忽略参数仅做状态切换:
父组件正确实现示例:
const [openRightDrawer, setOpenRightDrawer] = useState(false); const toggleDrawer = (open) => { setOpenRightDrawer(open); // 直接使用传入的open值更新状态 };
避免以下错误实现:
// 错误:忽略传入参数,仅切换状态 const toggleDrawer = () => { setOpenRightDrawer(prev => !prev); };
方案3:优化登出函数的执行顺序(可选)
若清空localStorage后会触发父组件的用户登录状态更新,可以调整登出函数的执行顺序,先清空存储再关闭Drawer,避免状态冲突:
子组件修改logout函数:
const logout = () => { localStorage.clear(); props.toggleClose(); toast.info("Successfully logged Out"); };
内容的提问来源于stack exchange,提问作者saranilango
相关产品推荐
相关产品推荐

