React-router: [v6] <Route path="app/*"> is matching apples/*

Created on 29 Jul 2020  路  4Comments  路  Source: ReactTraining/react-router

Version

6.0.0-beta.0

Test Case

https://codesandbox.io/s/heuristic-wiles-ycz48?file=/src/App.js

Steps to reproduce

In the sandbox above, click on the Cheeseburger link.

Expected Behavior

It should match the /cheeseburger/* path and render the <Cheeseburger /> component.

Actual Behavior

It gets caught by <Route path="/cheese/*"> and renders the <Cheese /> component.

Additionally, the <Link> in the <Cheese> component thinks we are in /cheese rather than /cheeseburger: the relative <Link to="details"> takes us to /cheese/details even though the current route is /cheeseburger.

This only happens the <Route>s are declared in this order, with the shorter word first:
<Route path="cheese/*" element={<Cheese />} />
<Route path="cheeseburger/*" element={<Cheeseburger />} />

It only happens when there is a trailing /*, e.g. <Route path="cheeseburger/*"> - I think you now always need a /* if there are sub-routes in the child component. It doesn't seem to happen if there is no /*, e.g. <Route path="cheeseburger">.

Most helpful comment

It appears that the compilePath function is at fault:

https://github.com/ReactTraining/react-router/blob/262b45dd8d6cbdc3a984259c5591ffc3de80d600/packages/react-router/index.tsx#L999

<Route path="/app/*" ... /> is compiling down to the RegExp match pattern: ^(/app)\/?(.*)$

This is causing matchPath('/app/*', '/apples') to match.

Incidentally, this also means that matchPath('/app', '/app?editing=true') doesn't match which makes little sense as search params shouldn't affect whether a route is matched.

This seems (possibly??) only to apply to Routes at the "root" level and not descendant or nested routes.

A more useful RegExp pattern for compilePath to resolve to in the case of /app/* would be ^(\/app)(\/.*|\?.*)?$

I'm not familiar enough with the inner workings of compilePath to submit a PR but perhaps this help to isolate the problem.

I, for one, am eagerly waiting for this to be fixed.

All 4 comments

Related to #7423

It appears that the compilePath function is at fault:

https://github.com/ReactTraining/react-router/blob/262b45dd8d6cbdc3a984259c5591ffc3de80d600/packages/react-router/index.tsx#L999

<Route path="/app/*" ... /> is compiling down to the RegExp match pattern: ^(/app)\/?(.*)$

This is causing matchPath('/app/*', '/apples') to match.

Incidentally, this also means that matchPath('/app', '/app?editing=true') doesn't match which makes little sense as search params shouldn't affect whether a route is matched.

This seems (possibly??) only to apply to Routes at the "root" level and not descendant or nested routes.

A more useful RegExp pattern for compilePath to resolve to in the case of /app/* would be ^(\/app)(\/.*|\?.*)?$

I'm not familiar enough with the inner workings of compilePath to submit a PR but perhaps this help to isolate the problem.

I, for one, am eagerly waiting for this to be fixed.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
You can add the fresh label to prevent me from taking any action.

This needs a fresh label.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

misterwilliam picture misterwilliam  路  3Comments

ryansobol picture ryansobol  路  3Comments

jzimmek picture jzimmek  路  3Comments

stnwk picture stnwk  路  3Comments

winkler1 picture winkler1  路  3Comments