Clicking the submit button to go to the next tab only changes the URL but not the tab and the component itself. How can I fix?

Viewed 245

I have these tabs for Step1 and Step2. In step1, I have this submit button to go to the next tab, it does update the URL, but the component does not update. It still stays on tab1. How can I fix this?

I kind of wanted to direct the user to the Step2 tab once the user has clicked the submit button in Step1

I recreated this in codesandbox: https://codesandbox.io/s/dawn-cloud-uxfe97?file=/src/Page.js

export default function App() {
  return (
    <div className="App">
      <Link to="/page">
        <button>Click this to go to the page</button>
      </Link>
      <Routes>
        <Route path="/page" element={<Page />}>
          <Route path="step1" element={<Step1 />} />
          <Route path="step2" element={<Step2 />} />
        </Route>
      </Routes>
    </div>
  );
}

Tabs

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

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

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

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

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

  const paths = ["/page/step1", "/page/step2"];
  const handleChange = (event, newValue) => {
    setValue(newValue);
    navigate(paths[newValue]);
  };

  return (
    <div>
      <Box sx={{ borderBottom: 1, borderColor: "divider" }}>
        <Tabs
          value={value}
          onChange={handleChange}
          aria-label="basic tabs example"
        >
          <Tab
            label="Step 1"
            {...a11yProps(0)}
            component={Link}
            to={`/page/step1`}
          />
          <Tab
            label="Step 2"
            {...a11yProps(1)}
            component={Link}
            to={`/page/step2`}
          />
        </Tabs>
      </Box>

      <TabPanel value={value} index={0}>
        <Step1 />
      </TabPanel>
      <TabPanel value={value} index={1}>
        <Step2 />
      </TabPanel>
    </div>
  );
};

export default Ordering;
1 Answers

You have a typo in the Step1 component, it is navigating to "/page/Step2" instead of `"/page/step2".

const Step1 = () => {
  const navigate = useNavigate();

  const handleSubmit = (e) => {
    e.preventDefault();
    navigate("/page/step2"); // <-- fix target path
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        step1
        <input type="submit" />
      </form>
    </div>
  );
};

The main issue with Page component is that is not "listening" for external route changes. You'll need to listen for these and manually update the value state to match the current path.

Example:

const Ordering = () => {
  const { pathname } = useLocation(); // <-- current path
  const navigate = useNavigate();
  const [value, setValue] = React.useState(0);

  const paths = useMemo(() => ["/page/step1", "/page/step2"], []);

  useEffect(() => {
    const value = paths.indexOf(pathname);
    setValue(value !== -1 ? value : 0); // <-- set the value to match path
  }, [pathname, paths]);

  const handleChange = (event, newValue) => {
    setValue(newValue);
    navigate(paths[newValue]);
  };

  return (
    <div>
      <Box sx={{ borderBottom: 1, borderColor: "divider" }}>
        <Tabs
          value={value}
          onChange={handleChange}
          aria-label="basic tabs example"
        >
          <Tab
            label="Step 1"
            {...a11yProps(0)}
            component={Link}
            to={`/page/step1`}
          />
          <Tab
            label="Step 2"
            {...a11yProps(1)}
            component={Link}
            to={`/page/step2`}
          />
        </Tabs>
      </Box>

      <TabPanel value={value} index={0}>
        <Step1 />
      </TabPanel>
      <TabPanel value={value} index={1}>
        <Step2 />
      </TabPanel>
    </div>
  );
};

Edit clicking-the-submit-button-to-go-to-the-next-tab-only-changes-the-url-but-not-th

Related