简体   繁体   中英

Material-UI tab indicator does not change when previous button is pressed

as far as now my code is working fine: The tab indicator is moving accordingly to the url of my tab. But there's a strange behaviour happening when the back button of the browser is getting pressed, the url is changing but the indicator stay on the same tab as before.

Here's the code:

import * as React from 'react';
import { Tabs, Tab, Box } from '@mui/material';
import { useNavigate } from 'react-router-dom';
import { HOME_PAGE } from '../../../router/customRouter';

const navigationsListTabs = [
  {
    id: 0,
    path: '/dev',
    label: 'Dev',
    isDisable: false,
  },
  {
    id: 1,
    path: '/images',
    label: 'Images',
    isDisable: false,
  },
  {
    id: 2,
    path: '/services',
    label: 'Services',
    isDisable: false,
  },
  {
    id: 3,
    path: '/users',
    label: 'users',
    isDisable: true,
  },
];

export const Header = () => {
  const [value, setValue] = React.useState(0);
  const navigate = useNavigate();

  React.useEffect(() => {
    navigate('/dev');
  }, []);

  function handleChange(event, newValue) {
    const selectedTab = navigationsListTabs.find((tab) => tab.id === newValue);
    navigate(HOME_PAGE + selectedTab.path);
    setValue(newValue);
  }
  return (
    <Box sx={{ width: '100%' }}>
      <Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
        <Tabs
          value={value}
          onChange={handleChange}
          data-testid="tabs-menu-component"
        >
          {navigationsListTabs.map((item) => (
            <Tab
              key={item.id}
              value={item.id}
              label={item.label}
              aria-label={item.label}
              disabled={item.isDisable}
            />
          ))}
        </Tabs>
      </Box>
    </Box>
  );
};

Tried so far: Using multiple conditions comparing url (not working):

  let url = window.location.pathname;
  console.log(url);

  const valueGetter = () => {
    if (url.includes('dev')) {
      return 0;
    } else if (url.includes('images')) {
      return 1;
    } else if (url.includes('services')) {
      return 2;
    } else {
      return 3;
    }
  };
  console.log(valueGetter());
  const [value, setValue] = React.useState(valueGetter);

Thanks to anyone who can help:)

If value is fully dependent on path , perhaps consider to always get value from pathname , instead of saving it as a state and handle both.

This example handles pathname with useLocation , so it gets updated by the hook when path changes. value is generated based on pathname .

Example:

import * as React from "react";
import { Tabs, Tab, Box } from "@mui/material";
import { useNavigate, useLocation } from "react-router-dom";
import { HOME_PAGE } from "../../../router/customRouter";

const navigationsListTabs = [
  {
    id: 0,
    path: "/dev",
    label: "Dev",
    isDisable: false,
  },
  {
    id: 1,
    path: "/images",
    label: "Images",
    isDisable: false,
  },
  {
    id: 2,
    path: "/services",
    label: "Services",
    isDisable: false,
  },
  {
    id: 3,
    path: "/users",
    label: "users",
    isDisable: true,
  },
];

export const Header = () => {
  const navigate = useNavigate();

  // 👇 Get value from pathname instead of saving it as state
  const { pathname } = useLocation();
  const currentTab = navigationsListTabs.find(
    (tab) => tab.path === `/${pathname.split("/")?.pop()}`
  );
  const value = currentTab ? currentTab?.id : 0;

  React.useEffect(() => {
    navigate("/dev");
  }, []);

  function handleChange(event, newValue) {
    const selectedTab = navigationsListTabs.find((tab) => tab.id === newValue);
    navigate(HOME_PAGE + selectedTab.path);
  }
  return (
    <Box sx={{ width: "100%" }}>
      <Box sx={{ borderBottom: 1, borderColor: "divider" }}>
        <Tabs
          value={value}
          onChange={handleChange}
          data-testid="tabs-menu-component"
        >
          {navigationsListTabs.map((item) => (
            <Tab
              key={item.id}
              value={item.id}
              label={item.label}
              aria-label={item.label}
              disabled={item.isDisable}
            />
          ))}
        </Tabs>
      </Box>
    </Box>
  );
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM