我有一个材料抽屉组件,在安装该组件时,需要检查本地存储并获取登录用户,然后将用户名放在模板中。
这是我的组件:
const PersistentDrawer = () => {
const [userLogged, setUserLogged] = useState({});
useEffect(() => {
setUserLogged(JSON.parse(localStorage.getItem('currentUser')))
// eslint-disable-next-line react-hooks/exhaustive-deps
},[])
const classes = drawerStyles();
const theme = useTheme();
const [open, setOpen] = useState(false);
const handleDrawerOpen = () => {
setOpen(true);
};
const handleDrawerClose = () => {
setOpen(false);
};
return (
<div className={classes.root}>
<CssBaseline />
<AppBar
position="fixed"
className={clsx(classes.appBar, {
[classes.appBarShift]: open,
})}
>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={handleDrawerOpen}
edge="start"
className={clsx(classes.menuButton, open && classes.hide)}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" noWrap>
Persistent drawer
</Typography>
</Toolbar>
</AppBar>
<Drawer
className={classes.drawer}
variant="persistent"
anchor="left"
open={open}
classes={{
paper: classes.drawerPaper,
}}
>
<img className={classes.logo} alt="Incca Sistemas" src="/assets/logo-incca.png"></img>
<div className={classes.drawerHeader}>
<Typography component="h6">{userLogged.login}</Typography>
<IconButton onClick={handleDrawerClose}>
{theme.direction === 'ltr' ? <ChevronLeftIcon /> : <ChevronRightIcon />}
</IconButton>
</div>
<Divider />
<List>
{['Inbox', 'Starred', 'Send email', 'Drafts'].map((text, index) => (
<ListItem button key={text}>
<ListItemIcon>{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
<Divider />
</Drawer>
<main
className={clsx(classes.content, {
[classes.contentShift]: open,
})}
>
</main>
</div>
);
}
export default PersistentDrawer
我收到:
无法在已卸载的组件上执行React状态更新。这是 无操作,但表示您的应用程序内存泄漏。修理, 取消useEffect清理中的所有订阅和异步任务 功能。
我该如何解决?
答案 0 :(得分:0)
将您的useEffect
更改如下:
useEffect(() => {
let neverMind = false;
const currentUser = JSON.parse(localStorage.getItem('currentUser'))
if(!neverMind) setUserLogged(currentUser)
return () => ( neverMind = true);
},[])
以某种方式将组件卸载,即使已卸载组件-您仍在尝试更新其状态。为避免这种情况,请设置一个标记,该标记将在卸载组件时(在返回的函数中)通知您,并且仅在标记未更改的情况下才更新状态。
有关如何使用“清理功能”的另一个示例,请参见React文档-https://reactjs.org/docs/hooks-effect.html#example-using-hooks-1
以下是Dan Abramov对这个问题的答案的链接-https://github.com/facebook/react/issues/14369#issuecomment-468267798
答案 1 :(得分:0)
无法在已卸载的组件上执行React状态更新。
尝试更改尚不存在的组件时,会发生此错误。
这通常是组件并行初始化(异步)的结果。
例如: 假设在第1行,第2行中两个组件A,B都被异步初始化。在第3行中,如果组件A尝试更新组件B,则很可能没有在时间线上创建组件B(第2行) 3(更新为B)已执行。
在这种情况下,将报告上述错误。
如何解决? 确定并更改异步代码块或函数,以确保在创建组件之前不尝试对其进行更新。