[英]Can't perform a React state update on an unmounted component with useEffect hook
[英]"Can't perform a React state update on an unmounted component" when i try to change state in useEffect()
我有一个材质抽屉组件,当组件挂载时,需要检查本地存储并获取登录用户,然后将用户名放入模板中。
这是我的组件:
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 清理函数中的所有订阅和异步任务。
我该如何解决这个问题?
将您的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
这是丹·阿布拉莫夫对这个问题的回答的链接 - https://github.com/facebook/react/issues/14369#issuecomment-468267798
无法对卸载的组件执行 React 状态更新。
当尝试更改尚不存在的组件时会发生此错误。
这通常是组件并行初始化(异步)的结果。
例如:假设两个组件 A、B 都在第 1、2 行异步初始化。在第 3 行中,如果组件 A 尝试更新组件 B,则组件 B(第 2 行)很可能没有被创建时间线 3(更新到 B)被执行。
在这种情况下,会报上述错误。
怎么修? 识别并更改异步代码块或函数,以确保在创建组件之前不会尝试对其进行更新。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.