如何制作breadcrumbs on site in examples folder of react-router repo有很好的例子。但我想知道如何用动态路线制作面包屑。
假设我们有这样的配置:
ReactDOM.render((
<Router history={browserHistory}>
<Route path="/projects" component={ProjectsApp}>
<IndexRoute component={ProjectsDashboard} />
<Route path=":projectId" component={ProjectBoard}>
<Route path=":taskId" component={ProjectTaskBoard}>
</Route>
</Route>
</Router>
), document.getElementById('app'));
我想做这样的事情:
项目(链接到'/ projects') - &gt; MyAwesomeProject(链接到'/ projects / 11'。从某处获取的标题(来自storeParams的id或其他方式的商店) - &gt; MyTask(链接到'/ projects / 11/999')
我怎样才能达到这个效果?有没有最佳做法?感谢。
答案 0 :(得分:5)
我们使用最为
的包react-breadcrumbs-dynamic适用于任何路由器(包括react-router v4)。
import {
BreadcrumbsProvider,
Breadcrumbs,
BreadcrumbsItem
} from 'react-breadcrumbs-dynamic'
const theApp = (
<BreadcrumbsProvider>
<App />
</BreadcrumbsProvider>
)
const App = (props) => (
return (
<div className="App">
<Breadcrumbs/>
{props.children}
</div>
)
}
const Page = (props) => (
<div>
<BreadcrumbsItem to='/'>Main Page</BreadcrumbsItem>
{props.children}
<Route exact path="/user" component={User} />
</div>
)
const User = (props) => (
<div>
<BreadcrumbsItem to='/user'>Home</BreadcrumbsItem>
<h2>Home</h2>
</div>
)
答案 1 :(得分:2)
使用react-router v4,所有路由都是动态的(虽然我认为仍然有编写静态定义的选项)。
正如@tbo在评论中所提到的,react-breadcrumbs是一个很好的解决方案,用于实现反应路由器版本3。您描述的动态面包屑甚至有一些变通方法(例如使用prepend
或getDisplayName
道具)。
in this issue正在进行一次对话,以确定如何最好地支持react-router v4,这肯定与你的问题有关。我已经挖掘了一堆其他面包屑组件库,这些存储库看起来都很难解决相同的静态路由问题,有些类似的问题已经打开以确定v4支持。
TLDR;如果您仍在使用react-router v3,则可以使react-breadcrumbs包适用于动态面包屑。如果您已迁移到v4,请继续关注,我希望很快会有更好的答案。
<强>更新强>:
在找不到符合我需求的其他解决方案后,我开发了一个解决方案并在react-breadcrumbs存储库上打开了pull request。 Auto-breadcrumb,如下所述,this discussion也是潜在的解决方案,但允许更少的自定义。如果您需要更多自定义,请订阅并随意评论或帮助pr。
答案 2 :(得分:1)
Auto-Breadcrumb似乎是最佳选择。我还没有找到一个很好的教程,但是有一个没有注释,但是公平simple demo可用。
答案 3 :(得分:1)
这是为嵌套导航和面包屑提供单一事实来源的解决方案。
该示例应用程序可在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>);
然后使用相同的导航结构构建面包屑。
答案 4 :(得分:0)
有几种方法可以做到这一点,还有几种开源解决方案(请参阅此处的答案:How do I create react-router v4 breadcrumbs?)
就个人而言,我更喜欢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}>
{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