I'm encountering an error when I try to clear the selected tab indicator from my Tabs navigation.
The element contains five individual Tab components in addition to a Button component that reroutes the user to our login screen.
If I click on the Login button, then the console displays the following error: "Material-UI: the value provided 5 to the Tabs component is invalid. None of the Tabs children have this value. You can provide one of the following values: 0, 1, 2, 3, 4."
Clicking on the button reroutes to the proper login path ("/login"), but leaves the previous tab showing as selected. However, if I refresh the page, then the selection indicator disappears as it's supposed to.
Any tips on how to remove this error and clear the selected indicator as soon as the Login button is pressed, rather than having to do a refresh?
import React, { useState, useEffect, Fragment } from 'react';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import useScrollTrigger from '@material-ui/core/useScrollTrigger';
import { makeStyles } from '@material-ui/styles';
import Tabs from '@material-ui/core/Tabs';
import Tab from '@material-ui/core/Tab';
import Button from '@material-ui/core/Button';
import { Link } from 'react-router-dom';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import useMediaQuery from '@material-ui/core/useMediaQuery';
import { useTheme } from '@material-ui/core/styles';
import SwipeableDrawer from '@material-ui/core/SwipeableDrawer';
import MenuIcon from '@material-ui/icons/Menu';
import IconButton from '@material-ui/core/IconButton';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';
import logo from '../../assets/logo.png';
function ElevationScroll(props) {
const { children, window } = props;
const trigger = useScrollTrigger({
disableHysteresis: true,
threshold: 0,
});
return React.cloneElement(children, {
elevation: trigger ? 4 : 4,
});
}
const useStyles = makeStyles(theme => ({
toolbarMargin: {
...theme.mixins.toolbar,
marginBottom: "1rem",
[theme.breakpoints.down("md")]: {
marginBottom: ".5rem",
transition: "all .2s ease-out"
},
[theme.breakpoints.down("xs")]: {
marginBottom: ".25rem",
transition: "all .2s ease-out"
}
},
logo: {
height: "2.5rem",
margin: "1rem 0 1rem 2rem",
transition: "all .2s ease-out",
[theme.breakpoints.down("md")]: {
height: "2rem",
transition: "all .2s ease-out",
marginLeft: "1.5rem"
},
[theme.breakpoints.down("xs")]: {
marginLeft: "1rem",
height: "1.5rem",
transition: "all .2s ease-out"
}
},
logoContainer: {
padding: 0,
backgroundColor: "transparent"
},
tabContainer: {
marginLeft: "auto"
},
tab: {
...theme.typography.tab,
minWidth: "1rem",
marginLeft: "2rem",
transition: "all .2s ease-out",
"&:hover": {
opacity: 1,
transition: "all .3s ease-out",
borderRadius: "3px",
}
},
button: {
margin: "0 3rem 0 1.5rem",
padding: "0 1.5rem",
height: "2.5rem"
},
styledIndicator: {
backgroundColor: theme.palette.primary.light
},
menu: {
backgroundColor: theme.palette.secondary.dark,
color: theme.palette.background.light,
borderRadius: "0px"
},
menuItem: {
...theme.typography.tab,
opacity: 0.7,
"&:hover": {
opacity: 1,
backgroundColor: theme.palette.common.black
}
},
drawerIcon: {
height: "2rem",
width: "2rem"
},
drawerIconContainer: {
marginLeft: "auto",
"&:hover": {
backgroundColor: "transparent"
}
},
drawer: {
backgroundColor: theme.palette.primary.dark
},
drawerItem: {
...theme.typography.button,
color: theme.palette.background.light,
paddingRight: "3.5rem",
opacity: .85
},
drawerItemLogin: {
...theme.typography.button,
backgroundColor: theme.palette.secondary.dark,
transition: "all .2s ease-out",
"&:hover": {
backgroundColor: theme.palette.common.black
},
"&.Mui-selected": {
backgroundColor: theme.palette.common.black,
"&:hover": {
backgroundColor: theme.palette.common.black
},
}
},
drawerItemSelected: {
opacity: 1
}
}))
export default function Header(props) {
const classes = useStyles();
const theme = useTheme();
const iOS = process.browser && /iPad|iPhone|iPod/.test(navigator.userAgent);
const matches = useMediaQuery(theme.breakpoints.down("md"));
const [openDrawer, setOpenDrawer] = useState(false);
const [value, setValue] = useState(0);
const [anchorEl, setAnchorEl] = useState(null);
const [openMenu, setOpenMenu] = useState(false);
const [selectedIndex, setSelectedIndex] = useState(0);
const handleChange = (e, newValue) => {
setValue(newValue);
}
const handleClick = (e) => {
setAnchorEl(e.currentTarget);
setOpenMenu(true);
}
const handleMenuItemClick = (e, idx) => {
setAnchorEl(null);
setOpenMenu(false);
setSelectedIndex(idx)
}
const handleClose = (e) => {
setAnchorEl(null);
setOpenMenu(false);
}
const menuOptions = [
{
name: "Brands",
link: "/brands",
}, {
name: "Overview",
link: "/overview",
}, {
name: "Use Cases",
link: "/usecases",
}, {
name: "Pricing",
link: "/pricing",
}
]
useEffect(() => {
switch (window.location.pathname) {
case "/":
if (value !== 0) {
setValue(0)
}
break;
case "/artists":
if (value !== 1) {
setValue(1)
}
break;
case "/brands":
if (value !== 2) {
setValue(2)
setSelectedIndex(0)
}
break;
case "/overview":
if (value !== 2) {
setValue(2)
setSelectedIndex(1)
}
break;
case "/usecases":
if (value !== 2) {
setValue(2)
setSelectedIndex(2)
}
break;
case "/pricing":
if (value !== 2) {
setValue(2)
setSelectedIndex(3)
}
break;
case "/about":
if (value !== 3) {
setValue(3)
}
break;
case "/contact":
if (value !== 4) {
setValue(4)
}
break;
case "/login":
if (value !== 5) {
setValue(5);
// setAnchorEl(null)
}
break;
default:
break
}
})
const tabs = (
<Fragment>
<Tabs
value={value}
onChange={handleChange}
className={classes.tabContainer}
classes={{ indicator: classes.styledIndicator }}
indicatorColor="#007EBB"
>
<Tab className={classes.tab} label="Home" component={Link} to={"/"} />
<Tab className={classes.tab} label="Artists" component={Link} to={"/artists"} />
<Tab
className={classes.tab}
label="Brands"
component={Link}
onMouseOver={e => handleClick(e)}
to={"/brands"}
/>
<Tab className={classes.tab} label="About" component={Link} to={"/about"} />
<Tab className={classes.tab} label="Contact" component={Link} to={"/contact"} />
</Tabs>
<Button className={classes.button} variant="contained" color="secondary" component={Link} to={"/login"}>
Login
</Button>
<Menu
anchorEl={anchorEl}
open={openMenu}
onClose={handleClose}
MenuListProps={{ onMouseLeave: handleClose }}
classes={{ paper: classes.menu }}
>
{menuOptions.map((option, idx) => (
<MenuItem
key={option}
component={Link}
to={option.link}
classes={{ root: classes.menuItem }}
onClick={(e) => {
handleMenuItemClick(e, idx);
setValue(2);
handleClose();
}}
selected={idx === selectedIndex && value === 1}
>
{option.name}
</MenuItem>
))}
</Menu>
</Fragment>
)
const drawer = (
<Fragment>
<SwipeableDrawer
disableBackdropTransition={!iOS}
disableDiscovery={iOS}
open={openDrawer}
onClose={() => setOpenDrawer(false)}
onOpen={() => setOpenDrawer(true)}
classes={{ paper: classes.drawer }}
>
<List disablePadding>
<ListItem onClick={() => { setOpenDrawer(false); setValue(0) }} divider button selected={value === 0} component={Link} to="/">
<ListItemText className={value === 0 ? [classes.drawerItem, classes.drawerItemSelected] : classes.drawerItem} disableTypography>Home</ListItemText>
</ListItem>
<ListItem onClick={() => { setOpenDrawer(false); setValue(0) }} divider button selected={value === 1} component={Link} to="/artists">
<ListItemText className={value === 1 ? [classes.drawerItem, classes.drawerItemSelected] : classes.drawerItem} disableTypography>Artists</ListItemText>
</ListItem>
<ListItem onClick={() => { setOpenDrawer(false); setValue(0) }} divider button selected={value === 2} component={Link} to="/brands">
<ListItemText className={value === 2 ? [classes.drawerItem, classes.drawerItemSelected] : classes.drawerItem} disableTypography>Brands</ListItemText>
</ListItem>
{/* <ListItem onClick={() => { setOpenDrawer(false); setValue(0) }} divider button selected={value === 2} component={Link} to="/overview">
<ListItemText className={value === 2 ? [classes.drawerItem, classes.drawerItemSelected] : classes.drawerItem} disableTypography>Overview</ListItemText>
</ListItem>
<ListItem onClick={() => { setOpenDrawer(false); setValue(0) }} divider button selected={value === 2} component={Link} to="/usecases">
<ListItemText className={value === 2 ? [classes.drawerItem, classes.drawerItemSelected] : classes.drawerItem} disableTypography>Use Cases</ListItemText>
</ListItem>
<ListItem onClick={() => { setOpenDrawer(false); setValue(0) }} divider button selected={value === 2} component={Link} to="/pricing">
<ListItemText className={value === 2 ? [classes.drawerItem, classes.drawerItemSelected] : classes.drawerItem} disableTypography>Pricing</ListItemText>
</ListItem> */}
<ListItem onClick={() => { setOpenDrawer(false); setValue(0) }} divider button selected={value === 3} component={Link} to="/about">
<ListItemText className={value === 3 ? [classes.drawerItem, classes.drawerItemSelected] : classes.drawerItem} disableTypography>About</ListItemText>
</ListItem>
<ListItem onClick={() => { setOpenDrawer(false); setValue(0) }} divider button selected={value === 4} component={Link} to="/contact">
<ListItemText className={value === 4 ? [classes.drawerItem, classes.drawerItemSelected] : classes.drawerItem} disableTypography>Contact</ListItemText>
</ListItem>
<ListItem onClick={() => { setOpenDrawer(false); setValue(0) }} className={classes.drawerItemLogin} divider button selected={value === 5} component={Link} to="/login">
<ListItemText
className={value === 5 ? [classes.drawerItem, classes.drawerItemSelected] : classes.drawerItem}
disableTypography
>Login</ListItemText>
</ListItem>
</List>
</SwipeableDrawer>
<IconButton
className={classes.drawerIconContainer}
onClick={() => setOpenDrawer(!openDrawer)}
disableRipple>
<MenuIcon className={classes.drawerIcon} />
</IconButton>
</Fragment >
)
return (
<React.Fragment>
<ElevationScroll>
<AppBar position="fixed" color="primary">
<Toolbar disableGutters={true}>
<Button
component={Link}
to="/"
disableRipple
className={classes.logoContainer}
onClick={() => setValue(0)}
>
<img src={logo} alt="Cuttime Logo" className={classes.logo} />
</Button>
{matches ? drawer : tabs}
</Toolbar>
</AppBar>
</ElevationScroll>
<div className={classes.toolbarMargin} />
</React.Fragment >
);
}