Brett DeWoody
Brett DeWoody

Reputation: 62773

React Router: Exclude strings from generic `/:slug` path

I'm attempting to setup the following UI based on routes

With this setup:

This is all in a nested route - /things. Which means the path from useRouteMatch returns /things

I have tried several combos with Switch, and attempted to use matchPath and useRouteMatch to differentiate /new from /:slug but with no luck. Every attempt results in one of the paths not returning the correct component.

For example:

<Switch>
  <Route path="/:slug(exclude "new")" exact component={ComponentC} />
  <Route path="/" exact component={ComponentA} />
</Switch>
<Route path="/new" component={ComponentB} />

Another option I've tried with no luck is to use regex on the slug, to match the slug pattern. Let's says the slug pattern is xxx-xxx-xxx-###, then I tried:

<Route path="/:slug((\w*-)*(\d*))" component={ComponentC) />

but this doesn't match the routes for some reason.

I'm thinking I could use location.pathname but this seems like a hack.

Is it possible to match and render routes as described above with standard <Route path="[something]" /> components with this setup?

Upvotes: 2

Views: 1018

Answers (1)

Brett DeWoody
Brett DeWoody

Reputation: 62773

This is why I love Stack Overflow. Asking the question often leads you to answer it yourself.

I was browsing the React Router docs for info on the regex and discovered the Route path property can accept an array of paths. So I went with this:

const { path } = useRouteMatch()

<Route path={[path, `${path}/new`]} exact component={ThingsList} />
<Switch>
  <Route path={`${path}/new`} render={() => <NewThing path={path} />} />
  <Route path={`${path}/:slug`} render={() => <Thing path={path} />} />
</Switch>

Upvotes: 1

Related Questions