Closed1

【React】パンくずリストの実装

JunpeiJunpei

前提として、@mui/material, @mui/icons-material, @emotion/styledの利用。

npm i @mui/material @mui/icons-material @emotion/styled

その上で今回は以下のように実装。

breadcrumbs.tsx
import React from 'react';
import { Breadcrumbs as MuiBreadcrumbs, Link as MuiLink, Typography } from '@mui/material';
import NavigateNextIcon from '@mui/icons-material/NavigateNext';
import styled from '@emotion/styled';

export interface BreadcrumbRef {
  title: string;
  navigateTo?: string;
}

interface Props {
  breadcrumbRefs: BreadcrumbRef[];
}

export const Breadcrumbs: React.FC<Props> = React.memo(function Breadcrumbs({ breadcrumbRefs }: Props) {
  return (
    <>
      <StyledBreadcrumbs aria-label="breadcrumb" separator={<NavigateNextIcon fontSize="small" />}>
        {breadcrumbRefs.map((breadcrumbRef) => {
          if (breadcrumbRef.navigateTo !== undefined) {
            return (
              <StyledMuiLink
                key={breadcrumbRef.title}
                underline="hover"
                color="inherit"
                href={breadcrumbRef.navigateTo}
              >
                {breadcrumbRef.title}
              </StyledMuiLink>
            );
          } else {
            return (
              <StyledTypography key={breadcrumbRef.title} color="text.primary">
                {breadcrumbRef.title}
              </StyledTypography>
            );
          }
        })}
      </StyledBreadcrumbs>
    </>
  );
});

const StyledBreadcrumbs = styled(MuiBreadcrumbs)`
  margin: 1%;
`;

const StyledMuiLink = styled(MuiLink)`
  cursor: pointer;
  font-size: 18px;
`;

const StyledTypography = styled(Typography)`
  font-size: 18px;
`;

これを呼び出すコンポーネントは、BreadcrumbRefsとして渡す配列を独自に定義。BreadcrumbsはnavigateToがundefineのものを「現在の位置」と判断してイイ感じのパンくずリストをrenderする。

  const breadcrumbRefs: BreadcrumbRef[] = useMemo(() => {
    const topRef = {
      title: 'Top',
      navigateTo: '/',
    };
    const firstRef = {
      title: firstTitle,
      navigateTo: `/first/${firstId ?? ''}`,
    };
    const secondRef = {
      title: secondTitle,
    };

    return [topRef, bookRef, subBookRef];
  }, [bookTitle, bookId, subBookTitle]);

https://mui.com/material-ui/react-breadcrumbs/

このスクラップは2023/02/28にクローズされました