"Can’t perform a React state update on an unmounted Component" when I try to change the state in useEffect

Asked

Viewed 141 times

0

I have a React UI Material Server and I need that when the component is mounted, check the localStorage and take the value of the logged in user to show in the template.

This is my component:

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

When I open/close my Drawer I get:

Can’t perform a React state update on an unmounted Component. This is a no-op, but it indicates a memory Leak in your application. To fix, Cancel all subscriptions and asynchronous tasks in a useEffect Cleanup Function.

Why does this happen?

1 answer

2


One of the ways to avoid this problem is to create a variable to control whether the component has already been loaded before trying to return the data from your localStorage, try the following:

const PersistentDrawer = () => {

  const [userLogged, setUserLogged] = useState({});
  useEffect(() => {
    let isCancelled = false;

    if (!isCancelled) {
        setUserLogged(JSON.parse(localStorage.getItem('currentUser')))
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }

    return () => {
      isCancelled = true;
    };

  },[])
  const classes = drawerStyles();
  const theme = useTheme();
  const [open, setOpen] = useState(false);

  const handleDrawerOpen = () => {
    setOpen(true);
  };

  const handleDrawerClose = () => {
    setOpen(false);
  };

  return (
    //Resto do código
  )
}

Here is an example:

https://codesandbox.io/s/use-local-variable-to-avoid-setstate-on-unmouted-component-6cmie

Here’s another way to solve:

https://codesandbox.io/s/useref-to-avoid-setstate-on-unmouted-component-p5gmb

Browser other questions tagged

You are not signed in. Login or sign up in order to post.