Как очистить индикатор выбранной вкладки, когда маршрут меняется на путь без вкладок - PullRequest
0 голосов
/ 22 февраля 2020

При попытке удалить индикатор выбранной вкладки из навигации по моим вкладкам возникает ошибка.

Элемент содержит пять отдельных компонентов Tab в дополнение к компоненту Button, который перенаправляет пользователя на экран входа в систему. .

Если я нажму на кнопку «Вход», на консоли отобразится следующая ошибка: «Material-UI: значение, предоставленное компоненту 5 вкладок, недопустимо. Ни у одного из дочерних элементов вкладок это значение отсутствует. Вы можете укажите одно из следующих значений: 0, 1, 2, 3, 4. "

При нажатии на кнопку перенаправляется на правильный путь входа в систему (" / login "), но при этом предыдущая вкладка отображается как выбранная. Однако, если я обновлю sh страницу, то индикатор выбора исчезнет, ​​как и должно быть.

Любые советы о том, как устранить эту ошибку и очистить выбранный индикатор, как только будет нажата кнопка входа в систему, скорее чем делать refre sh?

    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 >
      );
    }

1 Ответ

1 голос
/ 22 февраля 2020

Если вы не хотите, чтобы на странице входа в систему была выбрана вкладка, вам следует установить значение false, а не недопустимое значение (например, 5).

Из документации value реквизит для Tabs (https://material-ui.com/api/tabs/#props):

Значение текущего выбранного Tab. Если вы не хотите выбирать Tab, вы можете установить это свойство на false.

Ниже приведен пример, демонстрирующий это:

import React from "react";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/core/styles";
import AppBar from "@material-ui/core/AppBar";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
import Typography from "@material-ui/core/Typography";
import Box from "@material-ui/core/Box";
import Button from "@material-ui/core/Button";

function TabPanel(props) {
  const { children, value, index, ...other } = props;

  return (
    <Typography
      component="div"
      role="tabpanel"
      hidden={value !== index}
      id={`simple-tabpanel-${index}`}
      aria-labelledby={`simple-tab-${index}`}
      {...other}
    >
      {value === index && <Box p={3}>{children}</Box>}
    </Typography>
  );
}

TabPanel.propTypes = {
  children: PropTypes.node,
  index: PropTypes.any.isRequired,
  value: PropTypes.any.isRequired
};

function a11yProps(index) {
  return {
    id: `simple-tab-${index}`,
    "aria-controls": `simple-tabpanel-${index}`
  };
}

const useStyles = makeStyles(theme => ({
  root: {
    flexGrow: 1,
    backgroundColor: theme.palette.background.paper
  }
}));

export default function SimpleTabs() {
  const classes = useStyles();
  const [value, setValue] = React.useState(false);

  const handleChange = (event, newValue) => {
    setValue(newValue);
  };

  return (
    <div className={classes.root}>
      <AppBar position="static">
        <Tabs
          value={value}
          onChange={handleChange}
          aria-label="simple tabs example"
        >
          <Tab label="Item One" {...a11yProps(0)} />
          <Tab label="Item Two" {...a11yProps(1)} />
          <Tab label="Item Three" {...a11yProps(2)} />
        </Tabs>
      </AppBar>
      <TabPanel value={value} index={0}>
        Item One
      </TabPanel>
      <TabPanel value={value} index={1}>
        Item Two
      </TabPanel>
      <TabPanel value={value} index={2}>
        Item Three
      </TabPanel>
      {value !== false && (
        <Button onClick={() => setValue(false)}>De-select tab</Button>
      )}
    </div>
  );
}

Edit De-select tab

...