web-dev-qa-db-ja.com

react-router v4パンくずリストを作成するにはどうすればよいですか?

React-router v4パンくずリストを作成するにはどうすればよいですか?リアクションルーターV4 Webサイトで、問題チケットを介してこの質問をしてみました。彼らは 再帰的パス の例を見ると言った。 semantic-ui-react で作成したい

18
Monty

私は同じことをした後、あなたの質問は私を正しい方向に向けました。

これは私のために働いた:

const Breadcrumbs = (props) => (
    <div className="breadcrumbs">
        <ul className='container'>
            <Route path='/:path' component={BreadcrumbsItem} />
        </ul>
    </div>
)

const BreadcrumbsItem = ({ match, ...rest }) => (
    <span>
        <li className={match.isExact ? 'breadcrumb-active' : undefined}>
            <Link to={match.url || ''}>
                {match.url}
            </Link>
        </li>
        <Route path={`${match.url}/:path`} component={BreadcrumbsItem} />
    </span>
)
19
Felipe Taboada

私は自分のプロジェクトにsemantic-ui-reactを使用し、これを実行してlocation.pathnameに基づいてパンくずリストを作成しました。

export default (props) => {
    const paths = props.pathname.split('/').map((p, i, arr) => {
        if (i === 0) return {
            key: i, 
            content: (<Link to={'/'}>home</Link>), 
            active: (i === arr.length - 1), 
            link: (i < arr.length - 1)
        };

        if (i === arr.length - 1) return {
            key: i, 
            content: p, 
            active: (i === arr.length - 1)
        };

        return {
            key: i, 
            content: (<Link to={`${arr.slice(0, i + 1).join('/')}`}>{p}</Link>), 
            active: (i === arr.length - 1), 
            link: (i < arr.length - 1)}
        };
    );
    return <Breadcrumb icon='chevron right' sections={paths}/>;
};
6
jimmy

これは、react-routerからのpathnameを解析し、それに対する一致を返すHOCを使用して実行できます。もう少し冗長ですが、柔軟性が高く、読みやすいブレッドクラム構成オブジェクト配列を提供すると思います。

Breadcrumbs.jsx

import React from 'react';
import { NavLink } from 'react-router-dom';
import { withBreadcrumbs } from 'withBreadcrumbs';

const UserBreadcrumb = ({ match }) =>
  <span>{match.params.userId}</span>; // use match param userId to fetch/display user name

const routes = [
  { path: 'users', breadcrumb: 'Users' },
  { path: 'users/:userId', breadcrumb: UserBreadcrumb},
  { path: 'something-else', breadcrumb: ':)' },
];

const Breadcrumbs = ({ breadcrumbs }) => (
  <div>
    {breadcrumbs.map(({ breadcrumb, path, match }) => (
      <span key={path}>
        <NavLink to={match.url}> // wrap breadcrumb with semantic-ui element
          {breadcrumb}
        </NavLink>
        <span>/</span>
      </span>
    ))}
  </div>
);

export default withBreadcrumbs(routes)(Breadcrumbs);

withBreadcrumbs.js

import React from 'react';
import { matchPath, withRouter } from 'react-router';

const renderer = ({ breadcrumb, match }) => {
  if (typeof breadcrumb === 'function') { return breadcrumb({ match }); }
  return breadcrumb;
};

export const getBreadcrumbs = ({ routes, pathname }) => {
  const matches = [];

  pathname
    .replace(/\/$/, '')
    .split('/')
    .reduce((previous, current) => {
      const pathSection = `${previous}/${current}`;

      let breadcrumbMatch;

      routes.some(({ breadcrumb, path }) => {
        const match = matchPath(pathSection, { exact: true, path });

        if (match) {
          breadcrumbMatch = {
            breadcrumb: renderer({ breadcrumb, match }),
            path,
            match,
          };
          return true;
        }

        return false;
      });

      if (breadcrumbMatch) {
        matches.Push(breadcrumbMatch);
      }

      return pathSection;
    });

  return matches;
};

export const withBreadcrumbs = routes => Component => withRouter(props => (
  <Component
    {...props}
    breadcrumbs={
      getBreadcrumbs({
        pathname: props.location.pathname,
        routes,
      })
    }
  />
));

オープンソースHOCもここで入手できます。 https://github.com/icd2k3/react-router-breadcrumbs-hoc

4
Justin Schrader

これらの両方のアプローチの問題は、パンくずリストでパス名を使用することに制限されていることです。つまり、ルートをトレイルのプレゼンテーション名に関連付ける必要があります。

4
Adam Donahue

この簡単な解決策を試してください。

const Breadcrumbs = ({ ...rest, match }) => (
  <span>
      <Link to={match.url || ''} className={match.isExact ? 'breadcrumb active' : 'breadcrumb'}>
          {match.url.substr(match.url.lastIndexOf('/')+1, match.url.length)}
      </Link>
      <Route path={`${match.url}/:path`} component={Breadcrumbs} />
  </span>
)

あなたのCSS:

.breadcrumbs {
  background: #fff;
  margin-bottom: 15px;
}
.breadcrumb {
  margin-bottom: 0;
  line-height: 2.5;
  display: inline-block; 
}
.breadcrumb::before {
  display: inline-block;
  padding-right: 5px;
  padding-left: 5px;
  color: #818a91;
  content: "/"; }
.breadcrumb.active {
  color: #818a91; }

次に、次のように使用します。

<div className="container-fluid breadcrumbs">
  <Route path='/:path' component={Breadcrumbs} />
</div>

ハッピーコーディング!

2
Mwirabua Tim

react-router docから:<Route>コンポーネントは、場所が次のようにルートのパスと一致するときにコンポーネントの一部をレンダリングします。

<Route path={`${match.url}/:topicId`} component={Topic}/>

情報に対する基本的な責任は、この場合は<Topic>であるレンダリングされたコンポーネントに対して利用可能です。データを取得する方法を知っているか、すでにredux状態などを結び付けています。 <Topic>パンくずリストアイテムエージェントを単純にインスタンス化し、次のように必要なデータを渡します。

import {BreadcrumbsItem} from 'react-breadcrumbs-dynamic'

const Topic = ({ match, topic }) => (
  <div>
    <h3>
      {topic.title}
    </h3>

    <BreadcrumbsItem to={`${match.url}/${match.params.topicId}`}>
      {topic.title}
    </BreadcrumbsItem>

    ...
  </div>
)

それで全部です。 this answer のより完全な例。ここでライブ デモ

2
user394010

以下は、ネストされたナビゲーションとブレッドクラムの単一の真実のソースを提供するソリューションです。

サンプルアプリはGitHubで入手できます。 https://github.com/sneas/react-nested-routes-example

デモ: https://sneas.github.io/react-nested-routes-example/

ナビゲーション構成:

export const navigation = [
  {
    path: "/",
    label: "All categories",
    content: () => <AllCategories />,
    routes: [
      {
        path: "/electronics",
        label: "Electronics",
        content: () => <Electronics />,
        routes: [
          {
            path: "/accessories",
            label: "Accessories",
            content: () => <Accessories />,
            routes: [
              {
                path: "/usb-cables",
                label: "USB cables",
                content: () => <UsbCables />
              }
            ]
          },
          {
            path: "/headphones",
            label: "Headphones",
            content: () => <Headphones />
          }
        ]
      }
    ]
  }
];

ナビゲーションを再帰的にフラット化し、フラット配列にレンダリングする必要があります。

const routes = flattenRoutes(navigation);
return (<Router>
  {routes.map((route, index) => (
    <Route
      key={index}
      path={route.path}
      render={() => rouete.content}
    ></Route>
  ))}
</Router>);

次に、同じナビゲーション構造からブレッドクラムを構築します。

0
sneas