icd2k3/react-router-breadcrumbs-hoc

Optional Url Params

luke-unifymonitor opened this issue · 5 comments

Hi,

Love the project; thanks,

I have a problem with a path with an optional parameter.

When navigating to /sensor/register the breadcrumb shows:

Register Sensor

but navigating to /sensor/register/123 results in:

Register Sensor / Register Sensor

I have the following path setup in my routes.config - the offending route is at the bottom...

const routesConfig = [
  {
    path: '/hubs',
    exact: true,
    component: MyHubsContainer,
    breadcrumb: 'My Hubs'
  },
  {
    path: '/hubs/register',
    exact: true,
    component: RegisterHubContainer,
    breadcrumb: 'Register Hub'
  },
  {
    path: '/hubs/:hubId',
    exact: true,
    component: HubDashboardContainer,
    breadcrumb: HubBreadcrumbItem
  },
  {
    path: '/hubs/:hubId/sensor/:sensorId/:sensorName',
    exact: true,
    component: SensorDetailContainer,
    breadcrumb: SensorBreadcrumbItem
  },
  {
    path: '/sensor/instructions',
    exact: true,
    component: InstructionsContainer
  },
  {
    path: '/sensor/register/:hubId?',
    exact: true,
    component: RegisterSensorContainer,
    breadcrumb: 'Register Sensor'
  }
]
const MainRoutes = (props) =>
  <Switch>
    {routesConfig.map((route, i) =>
      <Route
        exact={route.exact}
        key={route.path}
        path={route.path}
        component={route.component}
      />)}
  </Switch>
const Breadcrumbs = ({ breadcrumbs }) =>
  <div>
    {breadcrumbs.map((breadcrumb, index) => (
      <Link key={breadcrumb.key} to={breadcrumb.props.match.url || ''}>
        {breadcrumb} {console.log('breadcrumb', breadcrumbs.length, breadcrumb)}
      </Link>
    ))}
  </div>

Any ideas?

👋 hey @luke-unifymonitor!

note: I removed my previous comment because I just had a chance to try out this approach below and it seems like it might work well for this use case.

Instead of a string, I recommend using a component breadcrumb that checks if the param is included or not:

const RegisterSensorBreadcrumb = ({ match }) => {
  // if the route includes `hubId` then return nothing for that breadcrumb
  // (alternatively you could also render a different breadcrumb IF the hubId is provided)
  if (match.params.hubId) { return null; }

  // if the route does NOT include `hubId` then return normal Register Sensor breadcrumb
  return <span>Register Sensor</span>;
};

const routesConfig = [
  {
    path: '/sensor/register/:hubId?',
    exact: true,
    component: RegisterSensorContainer,
    breadcrumb: RegisterSensorBreadcrumb,
  }
];

// /sensor/register == 'Register Sensor'
// /sensor/register/123 == 'Register Sensor'

In this case both /sensor/register and /sensor/register/123 paths will result in / Register Sensor.

Let me know if this works for you!

Gonna close this as the suggestion above should solve for this use case. If it doesn't, just let me know and I'll reopen this. Thanks!

Hi @icd2k3,

Apologies for not replying before. We had a re-think for the application and no longer needed the paths that caused the problem.

However, I did create this https://codesandbox.io/s/kok304yz1v and the console reads:

Warning: Encountered two children with the same key, /sensor/register/:hubId?. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.

Many thanks for your help.

🤔 I should fix that warning. I'll look into this case in the near future.

Thanks for the reply and the code sandbox @luke-unifymonitor !

Hey @luke-unifymonitor this key warning is fixed in 2.1.4. Here is the updated code sandbox: https://codesandbox.io/s/13j7vr75yl