Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix bug with nested optional segments #9727

Merged
merged 2 commits into from
Dec 14, 2022

Conversation

brophdawg11
Copy link
Contributor

@brophdawg11 brophdawg11 commented Dec 13, 2022

Found an issue with >2 optional nested segments due to the ordering in which we recombined the exploded paths.

The setup causing this was:

<Route path="dashboard">
  <Route path=":widget1?"> 
    <Route path=":widget2?">
      <Route path=":widget3?">

When we had 2 levels of nesting (which we have tests for) everythings fine. But once you get a third level and we get another level of recursion, we were incorrectly combining the results such that child routes interspersed prior to parent routes and we got /dashboard/:widget2 coming before /dashboard/:widget1

@changeset-bot
Copy link

changeset-bot bot commented Dec 13, 2022

🦋 Changeset detected

Latest commit: 0ce082e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
@remix-run/router Patch
react-router Patch
react-router-dom Patch
react-router-dom-v5-compat Patch
react-router-native Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

let routes = [
{
path: "/nested/:one?/:two?",
path: "/nested/:one?/:two?/:three?/:four?",
},
];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated some of these complex tests to include the equivalent manual route definitions and am asserting against both set of routes to ensure we're consistent with what the user would otherwise do manually.

@@ -515,6 +581,170 @@ describe("path matching with optional dynamic segments", () => {
});

test("consecutive optional dynamic segments in nested routes", () => {
let manuallyExploded = [
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's some ambiguity here - i.e., would the user put the value there first or not there first? I chose to assume that since we want to match deeper paths, that we would assume you would put the param there first, followed by the version without the param.

@@ -468,25 +469,35 @@ function explodeOptionalSegments(path: string): string[] {
if (rest.length === 0) {
// Intepret empty string as omitting an optional segment
// `["one", "", "three"]` corresponds to omitting `:two` from `/one/:two?/three` -> `/one/three`
return isOptional ? ["", required] : [required];
return isOptional ? [required, ""] : [required];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer the presence of the the param when exploding routes

.map((exploded) => {
// for absolute paths, ensure `/` instead of empty segment
return path.startsWith("/") && exploded === "" ? "/" : exploded;
});
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The flatmap was the weasel here since it caused he versions where this path was included to be interspersed with all child combinations when we want them all at the front.

// Assume
[a, b] // => [required, optional]
[c, d] // => [required, optional]
[e, f] // => [required, optional]

// We were getting this:
[a,b,c,d,e,f]

// But we wanted this:
[a,c,e,b,d,f]

@pcattori pcattori self-requested a review December 13, 2022 23:56
@pcattori pcattori merged commit 60102df into release-next Dec 14, 2022
@pcattori pcattori deleted the brophdawg11/fix-optional-segments-bug branch December 14, 2022 20:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants