icd2k3/react-router-breadcrumbs-hoc

Need help in route config

Closed this issue · 7 comments

When i go to route /scenario/edit/:id I need breadscrumb as Home/scenario/editwithid currently getting edit scenario twice.

export const scenarioManagerRoutes = [
	{ path: '/scenario/', component: ScenarioManagerHome, exact: true, breadcrumb: ()=> <React.Fragment><MyIcon class="icon-flow-tree"/>Scenario</React.Fragment>},
	{ path: '/scenario/create', component: ScenarioModelComposer, exact: true, breadcrumb: ()=> <React.Fragment><MyIcon class="icon-file2"/>Create Scenario</React.Fragment> },
	{ path: '/scenario/edit/:id?', component: ScenarioModelComposer, exact: true, breadcrumb: 'Edit Scenario', },
	{ path: '/scenario/details/:id?', component: ScenarioModelDetails, exact: true, breadcrumb: 'Scenario Details', },
];

Also if my route is /admin/apps/list I just want bread crumb as home/admin/list. How do i acheive this ?

When i go to route /scenario/edit/:id I need breadscrumb as Home/scenario/editwithid currently getting edit scenario twice.

By default, this HOC will attempt to create breadcrumbs for you. What you probably want to do is disable the default for this specific path.

Also if my route is /admin/apps/list I just want bread crumb as home/admin/list. How do i acheive this ?

Same kinda solution as above, you should be able to disable the default breadcrumb for /admin/apps

...Though if you find yourself disabling a lot of specific routes, the best solution might just be to disable all defaults! That way, you can explicitly define which and what breadcrumbs you want for all routes.

@amitkumarsingh here's a codesandbox of what you're describing (I think) https://codesandbox.io/s/k9p8k65pov

Note, in components/Breadcrumbs I'm using excludePaths: ["/scenario"] to avoid generating a default breadcrumb for this specific path section. Then, only the breadcrumbs for edit, create, and details will render.

Does not solve the purpose though.
Say i have route as

{ path: '/scenario/edit/:id?', component: ScenarioModelComposer, exact: true, breadcrumb: 'Edit Scenario', },
{ path: '/scenario/details/:id?', component: ScenarioModelDetails, exact: true, breadcrumb: 'Scenario Details', },

Then i want my breadcrumb as home > scenario > edit scenario but currently am getting home > scenario > edit scenario > edit scenario
How to solve this ?

@amitkumarsingh Oops, didn't mean to close the issue there 😬. I think I just realized what might be going on... you're seeing the double generated breadcrumbs only when the id param is present right?

The main issue here is that this HOC iterates through each section of the path looking for a breadcrumb match, so both /scenario/edit and scenario/edit/id match to the same breadcrumb. There are a couple ways to go about fixing this. Generally I'd recommend the latter fix, but either should fix your use case.

I also don't see a single example of a ? inside of a route in the react-router docs... are you sure you need those?

Quick solve

Use the excludePaths option to exclude the paths-section not containing the id param:

withBreadcrumbs(routes, {
  excludePaths: ["/scenario/edit", "/scenario/details"]
})(Breadcrumbs)

https://codesandbox.io/s/k9ozozvpy7

Probably better solve

Disable default generated breadcrumbs entirely and only use the ones provided in your route config. This also involves adjusting your route config from scenario/edit/:id? to scenario/edit/:id.
https://codesandbox.io/s/o9z4vz5l26

My App.js code is this.

<Provider store={store}>
				<BrowserRouter>
					<Bootstrap>
						<Switch>
							{routes.map((item, index) => {
								return (
									<SensemakerRoute
										key={index}
										path={item.path}
										exact={item.exact}
										component={item.component}
										store={store}
										routes={item.routes}
									/>
								);
							})}
						</Switch>
					</Bootstrap>
				</BrowserRouter>
			</Provider>

And my sensemaker code is this. Where am mounting the breadcrumb HOC and passing the breadcrumb as props ?

const SensemakerRoute = ({ component: Component, store, ...rest }: any) => {
	return (
		<Route
			{...rest}
			render={(props) => {
				return isAuthenticated(store, props) ? (
					<Component {...props} breadcrumbs={rest.breadcrumbs} />
				) : (
					<Redirect to="/home" />
				);
			}}
		/>
	);
};

export default withBreadcrumbs(routes ,{
	disableDefaults: true,
})(SensemakerRoute);

But in your case your are mounting HOC on breadcrumb component itself ? Not working for me.

It shouldn't matter where it is mounted as long as it is somewhere within a react-router Router component. Either codesandbox link above should fix the issue for you. Make sure to check components/Breadcrumbs and modules/routeConfig in each. The excludePaths option should be easier to validate first.

It worked. Thanks 👍