javascript - React router v4 breadcrumbs - Stack Overflow

I am trying to implement React Router Breadcrumbs for v4Following are my routes:const routes = {'

I am trying to implement React Router Breadcrumbs for v4

Following are my routes:

    const routes = {
      '/': 'Home',
      '/page1': 'Page 1',
      '/page2': 'Page 2'
    };

I could put the breadcrumbs using this library in my application, however I am having following questions:

Que. #1:

When I click on Home in my breadcrumbs, I can see the URL changes to http://localhost:8080 However, browser still shows the same page I am on.

Que. #2:

When I navigate to Page2 from Page1, url changes from http://localhost:8080/page1 to http://localhost:8080/page2.

So the breadcrumbs shown changes to Home / Page 2 instead of changing like Home / Page 1 / Page 2

I know this may be because the url just has /page2 after hostname. But, can I achieve the display like: Home / Page 1 / Page 2?

Below is the code in my main App.jsx:

<Router>
  <div>
    <Link to="/"><div className="routerStyle"><Glyphicon glyph="home" /></div></Link>
    <Route exact path="/" ponent={LandingPage}/>
    <Route path="/page1" ponent={Page1}/>
    <Route path="/page2" ponent={Page2}/>
  </div>
</Router>

and if I use like belowto cater for breadcrumbs, then my page2 gets rendered below page1 stuff:

    <Router>
      <div>
        <Link to="/"><div className="routerStyle"><Glyphicon glyph="home" /></div></Link>
        <Route exact path="/" ponent={LandingPage}/>
        <Route path="/page1" ponent={Page1}/>
        <Route path="/page1/page2" ponent={Page2}/>
      </div>
    </Router>

Answer:

Que. #1: No need to wrap <Breadcrumbs ..../> element inside <Router> element inside each Component of application. This may be because, inclusion of <Router> element inside each Component leads to "nesting" of Router elements (note we have Router tag in landing page as well); which does not work with react router v4.

Que. #2: Refer to answer formally marked here (answered by palsrealm below)

I am trying to implement React Router Breadcrumbs for v4

Following are my routes:

    const routes = {
      '/': 'Home',
      '/page1': 'Page 1',
      '/page2': 'Page 2'
    };

I could put the breadcrumbs using this library in my application, however I am having following questions:

Que. #1:

When I click on Home in my breadcrumbs, I can see the URL changes to http://localhost:8080 However, browser still shows the same page I am on.

Que. #2:

When I navigate to Page2 from Page1, url changes from http://localhost:8080/page1 to http://localhost:8080/page2.

So the breadcrumbs shown changes to Home / Page 2 instead of changing like Home / Page 1 / Page 2

I know this may be because the url just has /page2 after hostname. But, can I achieve the display like: Home / Page 1 / Page 2?

Below is the code in my main App.jsx:

<Router>
  <div>
    <Link to="/"><div className="routerStyle"><Glyphicon glyph="home" /></div></Link>
    <Route exact path="/" ponent={LandingPage}/>
    <Route path="/page1" ponent={Page1}/>
    <Route path="/page2" ponent={Page2}/>
  </div>
</Router>

and if I use like belowto cater for breadcrumbs, then my page2 gets rendered below page1 stuff:

    <Router>
      <div>
        <Link to="/"><div className="routerStyle"><Glyphicon glyph="home" /></div></Link>
        <Route exact path="/" ponent={LandingPage}/>
        <Route path="/page1" ponent={Page1}/>
        <Route path="/page1/page2" ponent={Page2}/>
      </div>
    </Router>

Answer:

Que. #1: No need to wrap <Breadcrumbs ..../> element inside <Router> element inside each Component of application. This may be because, inclusion of <Router> element inside each Component leads to "nesting" of Router elements (note we have Router tag in landing page as well); which does not work with react router v4.

Que. #2: Refer to answer formally marked here (answered by palsrealm below)

Share Improve this question edited Oct 11, 2017 at 19:10 Akshay Lokur asked Oct 11, 2017 at 12:47 Akshay LokurAkshay Lokur 7,52615 gold badges48 silver badges69 bronze badges 2
  • any react codes? – Rei Dien Commented Oct 11, 2017 at 13:48
  • Its same as the URL given in question, thanks – Akshay Lokur Commented Oct 11, 2017 at 15:40
Add a ment  | 

3 Answers 3

Reset to default 2

Your breadcrumbs are based on links and they work as designed. To display the pages, you need to set up a Switch with Routes in it which would load the appropriate ponents when the path changes. Something like

<Switch> 
    <Route path='/' ponent={Home}/>
    <Route path='/page1' ponent={Page1}/>
    <Route path='/page2' ponent={Page2}/>
</Switch>

If you want the breadcrumb to show Home/Page1/Page2 your routes should be '/page1/page2' : 'Page 2'. The Route should also change accordingly.

Edit: Your Router should be

 <Router>
      <div>
        <Link to="/"><div className="routerStyle"><Glyphicon glyph="home" /></div></Link>
        <Switch>
        <Route exact path="/" ponent={LandingPage}/>
        <Route exact path="/page1" ponent={Page1}/>
        <Route path="/page1/page2" ponent={Page2}/>
        </Switch>
      </div>
    </Router>

This can also be acplished with a HOC which would allow you to use a route config object to set breadcrumbs instead. I've open-sourced it here, but the source code is below as well:

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}>
          {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,
      })
    }
  />
));

The following ponent should return a breadcrumb at any depth, except on the home page (for obvious reasons). You won't need React Router Breadcrumb. My first public contribution, so if I'm missing an essential part, it would be great if somebody could point it out. I added &raquo; for crumbs splits, but you can obviously update that to match what you need.

import React from 'react'
import ReactDOM from 'react-dom'
import { Route, Link } from 'react-router-dom'
// styles
require('./styles/_breadcrumbs.scss')

// replace underscores with spaces in path names
const formatLeafName = leaf => leaf.replace('_', ' ')

// create a path based on the leaf position in the branch
const formatPath = (branch, index) => branch.slice(0, index + 1).join('/')

// output the individual breadcrumb links
const BreadCrumb = props => {
  const { leaf, index, branch } = props,
    leafPath = formatPath(branch, index),
    leafName = index == 0 ? 'home' : formatLeafName(leaf),
    leafItem =
      index + 1 < branch.length 
        ? <li className="breadcrumbs__crumb">
          <Link to={leafPath}>{leafName}</Link>
          <span className="separator">&raquo;</span>
        </li>
        : <li className="breadcrumbs__crumb">{leafName}</li>
  // the slug doesn't need a link or a separator, so we output just the leaf name

  return leafItem
}

const BreadCrumbList = props => {
  const path = props.match.url,
    listItems =
      // make sure we're not home (home return '/' on url)
      path.length > 1
      && path
        // create an array of leaf names
        .split('/')
        // send our new array to BreadCrumb for formating
        .map((leaf, index, branch) => 
          <BreadCrumb leaf={leaf} index={index} branch={branch} key={index} />
        )

  // listItem will exist anywhere but home
  return listItems && <ul className="breadcrumbs">{listItems}</ul>
}

const BreadCrumbs = props => 
  <Route path="/*" render={({ match }) => <BreadCrumbList match={match} />} />


export default BreadCrumbs

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744251330a4565180.html

相关推荐

  • javascript - React router v4 breadcrumbs - Stack Overflow

    I am trying to implement React Router Breadcrumbs for v4Following are my routes:const routes = {'

    8天前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信