3

I want to change this BreadCrumb component that was done with react-router v5 to react router v6.

import React from "react";
import {
  Breadcrumbs as MUIBreadcrumbs,
  Link,
  Typography
} from "@material-ui/core";
import { withRouter } from "react-router-dom";

const Breadcrumbs = props => {
  const {
    history,
    location: { pathname }
  } = props;
  const pathnames = pathname.split("/").filter(x => x);
  return (
    <MUIBreadcrumbs aria-label="breadcrumb">
      {pathnames.length > 0 ? (
        <Link onClick={() => history.push("/")}>Home</Link>
      ) : (
        <Typography> Home </Typography>
      )}
      {pathnames.map((name, index) => {
        const routeTo = `/${pathnames.slice(0, index + 1).join("/")}`;
        const isLast = index === pathnames.length - 1;
        return isLast ? (
          <Typography key={name}>{name}</Typography>
        ) : (
          <Link key={name} onClick={() => history.push(routeTo)}>
            {name}
          </Link>
        );
      })}
    </MUIBreadcrumbs>
  );
};

export default withRouter(Breadcrumbs);

I try looking out information about how to use the withRouter now it seems that we can use hooks, useLocation and useHistory, as I'm new to React I don't know how to implement those, the code above is in this sandbox.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • Can you update your question to include a [minimal, complete, and reproducible code example](https://stackoverflow.com/help/minimal-reproducible-example) for your attempt at the conversion, including any issues you are facing? – Drew Reese Mar 23 '22 at 19:03

1 Answers1

4

Regarding just this Breadcrumbs component, since it is a function component you can use the React hooks. The v5 useHistory hook was replaced by the useNavigate hook that returns a navigate function instead of a history object. useLocation hook returns the same location object.

Example:

import React from "react";
import {
  Breadcrumbs as MUIBreadcrumbs,
  Link,
  Typography
} from "@material-ui/core";
import { useNavigate, useLocation } from "react-router-dom";

const Breadcrumbs = () => {
  const navigate = useNavigate();
  const { pathname } = useLocation();

  const pathnames = pathname.split("/").filter(Boolean);

  return (
    <MUIBreadcrumbs aria-label="breadcrumb">
      {pathnames.length ? (
        <Link onClick={() => navigate("/")}>Home</Link>
      ) : (
        <Typography> Home </Typography>
      )}
      {pathnames.map((name, index) => {
        const routeTo = `/${pathnames.slice(0, index + 1).join("/")}`;
        const isLast = index === pathnames.length - 1;
        return isLast ? (
          <Typography key={name}>{name}</Typography>
        ) : (
          <Link key={name} onClick={() => navigate(routeTo)}>
            {name}
          </Link>
        );
      })}
    </MUIBreadcrumbs>
  );
};

export default Breadcrumbs;

You'll OFC need to follow the upgrade from v5 to upgrade the rest of your app to use the v6 component APIs so routing and navigation and accessing the old "route props" works.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • I have a follow-up question with this component, let's say if I'm navigating between windows with forms and I don't want to lose data that was entered but not submitted, what can I implement in this component? – Fernado Castellon Mar 24 '22 at 14:39
  • @FernadoCastellon You very likely will need to persist this form data/state higher in the app's ReactTree such that the component it's located in remains mounted while navigating between routes. This is where a React context and/or Redux is helpful. – Drew Reese Mar 24 '22 at 23:28