title: React, how do I persist the state of side drawer selected list item with router?
body: <p>I'm using react-router and material UI. I integrated the routes with my material UI persist drawer list items with some custom styling like when I click on a list item it highlights it. But I'm facing an issue when I refresh the page my selected list item gets reset, even though I'm still on the same page. Can anyone tell me how do I persist the selected list item even if a page gets refreshed?</p>
  <p><strong>Inshort</strong>: <em>Issue</em>- when I refresh the page my drawer list item selected color get reset to top item even though I'm on the same page.</p>
  <p>Here is the gif to demonstrate my issue<a href="https://i.stack.imgur.com/gxq1K.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/gxq1K.gif" alt="enter image description here" /></a></p>
  <p>Here is my sandbox code <a href="https://codesandbox.io/s/whats-the-best-way-to-separate-the-routes-in-react-router-dom-forked-whr5o?file=/src/App.js" rel="nofollow noreferrer">link</a></p>
  <p>Below is the code for the same</p>
  <p><strong>Note:</strong> I would suggest you go through my code sandbox it'll be better for you to lookup in code. Thank you</p>
  <p><strong>App.js</strong></p>
  <pre><code>import { Switch, Route } from &quot;react-router-dom&quot;;
  
  import Login from &quot;./pages/Login&quot;;
  import Dashboard from &quot;./pages/Dashboard&quot;;
  import &quot;./styles.css&quot;;
  
  
  export default function App() {
    return (
      &lt;div className=&quot;App&quot;&gt;
        &lt;Switch&gt;
          &lt;Route path=&quot;/dashboard&quot; component={Dashboard} /&gt;
          &lt;Route path=&quot;/&quot; exact component={Login} /&gt;
        &lt;/Switch&gt;
      &lt;/div&gt;
    );
  }
  
  </code></pre>
  <p><strong>Dashboard.jxs for nested routes in dashboard</strong></p>
  <pre><code>import { Switch, Redirect, Route, useRouteMatch } from &quot;react-router-dom&quot;;
  import Home from &quot;./Home&quot;;
  import About from &quot;./About&quot;;
  import NavBar from &quot;../components/NavBar&quot;;
  
  const Dashboard = () =&gt; {
    const { path } = useRouteMatch();
    return (
      &lt;&gt;
        &lt;NavBar&gt;
          &lt;Switch&gt;
            &lt;Route path={`${path}/about`} component={About} /&gt;
            &lt;Route path={`${path}/home`} component={Home} /&gt;
            &lt;Redirect to={`${path}/home`} /&gt;
          &lt;/Switch&gt;
        &lt;/NavBar&gt;
      &lt;/&gt;
    );
  };
  
  export default Dashboard;
  
  </code></pre>
  <p><strong>NavBar.js</strong></p>
  <pre><code>import React from &quot;react&quot;;
  import clsx from &quot;clsx&quot;;
  import { makeStyles, useTheme } from &quot;@material-ui/core&quot;;
  import CssBaseline from &quot;@material-ui/core/CssBaseline&quot;;
  import AppBar from &quot;@material-ui/core/AppBar&quot;;
  import Toolbar from &quot;@material-ui/core/Toolbar&quot;;
  import Typography from &quot;@material-ui/core/Typography&quot;;
  import IconButton from &quot;@material-ui/core/IconButton&quot;;
  import MenuIcon from &quot;@material-ui/icons/Menu&quot;;
  import { useRouteMatch } from &quot;react-router-dom&quot;;
  import SideDrawer from &quot;./SideDrawer&quot;;
  
  const drawerWidth = 240;
  
  const useStyles = makeStyles((theme) =&gt; ({
    root: {
      display: &quot;flex&quot;
    },
    appBar: {
      transition: theme.transitions.create([&quot;margin&quot;, &quot;width&quot;], {
        easing: theme.transitions.easing.sharp,
        duration: theme.transitions.duration.leavingScreen
      })
    },
    appBarShift: {
      width: `calc(100% - ${drawerWidth}px)`,
      marginLeft: drawerWidth,
      transition: theme.transitions.create([&quot;margin&quot;, &quot;width&quot;], {
        easing: theme.transitions.easing.easeOut,
        duration: theme.transitions.duration.enteringScreen
      })
    },
    menuButton: {
      marginRight: theme.spacing(2)
    },
    hide: {
      display: &quot;none&quot;
    },
    drawer: {
      width: drawerWidth,
      flexShrink: 0
    },
    drawerPaper: {
      width: drawerWidth
    },
    drawerHeader: {
      display: &quot;flex&quot;,
      alignItems: &quot;center&quot;,
      padding: theme.spacing(0, 1),
      // necessary for content to be below app bar
      ...theme.mixins.toolbar,
      justifyContent: &quot;flex-end&quot;
    },
    content: {
      flexGrow: 1,
      padding: theme.spacing(3),
      transition: theme.transitions.create(&quot;margin&quot;, {
        easing: theme.transitions.easing.sharp,
        duration: theme.transitions.duration.leavingScreen
      }),
      marginLeft: -drawerWidth
    },
    contentShift: {
      transition: theme.transitions.create(&quot;margin&quot;, {
        easing: theme.transitions.easing.easeOut,
        duration: theme.transitions.duration.enteringScreen
      }),
      marginLeft: 0
    }
  }));
  
  export default function NavBar({ children }) {
    const classes = useStyles();
    const theme = useTheme();
    const [open, setOpen] = React.useState(true);
  
    const { url } = useRouteMatch();
  
    const handleDrawerOpen = () =&gt; {
      if (!open) {
        setOpen(true);
      } else {
        setOpen(false);
      }
    };
  
    return (
      &lt;div className={classes.root}&gt;
        &lt;CssBaseline /&gt;
        &lt;AppBar
          position=&quot;fixed&quot;
          className={clsx(classes.appBar, {
            [classes.appBarShift]: open
          })}
        &gt;
          &lt;Toolbar&gt;
            &lt;IconButton
              color=&quot;inherit&quot;
              aria-label=&quot;open drawer&quot;
              onClick={handleDrawerOpen}
              edge=&quot;start&quot;
              className={clsx(classes.menuButton)}
            &gt;
              &lt;MenuIcon /&gt;
            &lt;/IconButton&gt;
            &lt;Typography variant=&quot;h6&quot; noWrap&gt;
              Persistent drawer
            &lt;/Typography&gt;
          &lt;/Toolbar&gt;
        &lt;/AppBar&gt;
        {/* child compoent to render side drawer and state is passing to open &amp; close */}
        &lt;SideDrawer open={open} /&gt;
        &lt;main
          className={clsx(classes.content, {
            [classes.contentShift]: open
          })}
        &gt;
          &lt;div className={classes.drawerHeader} /&gt;
          {children}
        &lt;/main&gt;
      &lt;/div&gt;
    );
  }
  
  </code></pre>
  <p><strong>SideDrawer.js its a child component inside NavBar.js</strong></p>
  <pre><code>import {
    useTheme,
    Divider,
    Drawer,
    IconButton,
    List,
    ListItem,
    ListItemIcon,
    makeStyles
  } from &quot;@material-ui/core&quot;;
  import React from &quot;react&quot;;
  import ChevronLeftIcon from &quot;@material-ui/icons/ChevronLeft&quot;;
  import ChevronRightIcon from &quot;@material-ui/icons/ChevronRight&quot;;
  import DrawerList from &quot;./DrawerList&quot;;
  
  const drawerWidth = 240;
  
  const useStyles = makeStyles((theme) =&gt; ({
    drawer: {
      width: drawerWidth,
      flexShrink: 0
    },
    drawerPaper: {
      width: drawerWidth
    },
    drawerHeader: {
      display: &quot;flex&quot;,
      alignItems: &quot;center&quot;,
      padding: theme.spacing(0, 1),
      // necessary for content to be below app bar
      ...theme.mixins.toolbar,
      justifyContent: &quot;flex-end&quot;
    }
  }));
  
  const SideDrawer = (props) =&gt; {
    const theme = useTheme();
    const classes = useStyles();
    const { open } = props;
    return (
      &lt;Drawer
        className={classes.drawer}
        variant=&quot;persistent&quot;
        anchor=&quot;left&quot;
        open={open}
        classes={{
          paper: classes.drawerPaper
        }}
      &gt;
        &lt;div className={classes.drawerHeader}&gt;
          &lt;h1&gt;Header&lt;/h1&gt;
        &lt;/div&gt;
        &lt;Divider /&gt;
        &lt;List&gt;
          {/* my component to render list of icons in side drawer */}
          &lt;DrawerList /&gt;
        &lt;/List&gt;
      &lt;/Drawer&gt;
    );
  };
  
  export default SideDrawer;
  
  </code></pre>
  <p><strong>DrawerList.js child component of SideDrawer.js</strong> <em><strong>Issue is arising here</strong></em></p>
  <pre><code>import React, { useState } from &quot;react&quot;;
  import ListItem from &quot;@material-ui/core/ListItem&quot;;
  import ListItemIcon from &quot;@material-ui/core/ListItemIcon&quot;;
  import { DashboardOutlined, AddCircleOutline } from &quot;@material-ui/icons&quot;;
  import ListItemText from &quot;@material-ui/core/ListItemText&quot;;
  import { makeStyles, Typography } from &quot;@material-ui/core&quot;;
  import Box from &quot;@material-ui/core/Box&quot;;
  import { Link, useRouteMatch } from &quot;react-router-dom&quot;;
  
  const useStyles = makeStyles((theme) =&gt; ({
    root: {
      marginTop: theme.spacing(1)
    },
    iconStyle: {
      margin: theme.spacing(0, 0),
      color: &quot;#676767&quot;
    },
    iconTitle: {
      margin: theme.spacing(0, 0, 0, 1),
      color: &quot;#676767&quot;
    },
    listItem: {
      &quot;&amp;.Mui-selected&quot;: {
        // it is used to change external svg color during click
        &quot;&amp; path&quot;: {
          fill: &quot;#fff&quot;
        },
        margin: theme.spacing(1.5, 1)
      }
    }
  }));
  
  const DrawerList = ({ children }) =&gt; {
    console.log(children);
    const [selectedIndex, setSelectedIndex] = useState(0);
    const classes = useStyles();
  
    const { url } = useRouteMatch();
  
    const itemList = [
      {
        text: &quot;Home&quot;,
        icon: &lt;DashboardOutlined /&gt;,
        keys: &quot;home&quot;,
        to: `${url}/home`
      },
      {
        text: &quot;Appointment&quot;,
        icon: &lt;AddCircleOutline /&gt;,
        keys: &quot;about&quot;,
        to: `${url}/about`
      }
    ];
  
    const ListData = () =&gt;
      itemList.map((item, index) =&gt; {
        const { text, icon, to, keys } = item;
  
        return (
          &lt;ListItem
            className={classes.listItem}
            button
            key={keys}
            to={to}
            component={Link}
            selected={index === selectedIndex}
            onClick={(e) =&gt; handleListItemClick(e, index)}
            style={
              selectedIndex === index
                ? {
                    background: &quot;#3f51b5&quot;,
                    width: 200,
                    marginLeft: 8,
                    paddingLeft: 10,
                    borderRadius: 4,
                    boxShadow: &quot;2px 3px 6px rgba(0, 0, 0, 0.3)&quot;
                  }
                : {}
            }
          &gt;
            &lt;ListItemIcon
              className={classes.iconStyle}
              style={selectedIndex === index ? { color: &quot;#fff&quot; } : {}}
            &gt;
              {icon}
              &lt;ListItemText&gt;
                &lt;Typography
                  component=&quot;div&quot;
                  className={classes.iconTitle}
                  style={selectedIndex === index ? { color: &quot;#fff&quot; } : {}}
                &gt;
                  &lt;Box fontWeight={700} fontSize={13.8}&gt;
                    {text}
                  &lt;/Box&gt;
                &lt;/Typography&gt;
              &lt;/ListItemText&gt;
            &lt;/ListItemIcon&gt;
          &lt;/ListItem&gt;
        );
      });
  
    const handleListItemClick = (e, index) =&gt; {
      setSelectedIndex(index);
    };
  
    return (
      &lt;div className={classes.root}&gt;
        &lt;ListData /&gt;
      &lt;/div&gt;
    );
  };
  
  export default DrawerList;
  
  </code></pre>