Search code examples
reactjsreact-routerbreadcrumbscustom-component

Change BreadCrumb component that was done with react-router v5 to react router v6


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.


Solution

  • 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.