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

[Feature]: Optional routing parameters in v6 #8381

Closed
vocko opened this issue Nov 23, 2021 · 10 comments
Closed

[Feature]: Optional routing parameters in v6 #8381

vocko opened this issue Nov 23, 2021 · 10 comments
Labels

Comments

@vocko
Copy link

vocko commented Nov 23, 2021

What is the new or updated feature that you are suggesting?

In the previous versions, we could specify optional parameters using the ? character in the end of the name. This has been dropped due to the removal of the regular expressions support. As I can understand the reasoning behind the added complexity from regular expressions, I believe this particular feature was very useful and it should be doable using just string functions.

Why should this feature be included?

At the moment if there are multiple paths for the same element, you have to register all of them separately. Imagine element dashboard that can take plenty of optional parameters.

In the v5 we could specify pathlike this:

<Route path="/dashboard/:param1?/:param2?/:param3?/:param4?">
    <Dashboard />
</Route>

And /dashboard, /dashboard/1, ..., /dashboard/1/2/3/4 were all valid routes.

In v6, we have to register each route separately:

<Route path="dashboard" element={<Dashboard />} />
<Route path="dashboard/:param1" element={<Dashboard />} />
<Route path="dashboard/:param1/:param2" element={<Dashboard />} />
<Route path="dashboard/:param1/:param2/:param3" element={<Dashboard />} />
<Route path="dashboard/:param1/:param2/:param3/:param4" element={<Dashboard />} />

This is unnecessarily verbose.

If there is any better solution under the new version, I would like to hear about it, I might have missed something as I have only upgraded to v6 recently.

@vocko vocko added the feature label Nov 23, 2021
@vocko
Copy link
Author

vocko commented Nov 24, 2021

I have realised that this is a sub-query of #8254. If it gets answered/resolved there, this issue can be closed. However, I still believe, regardless of the regex path resolution (moved to a separated library, as suggested, is imho the best solution), optional parameters should be a part of the base router logic.

@Haraldson
Copy link

Haraldson commented Dec 8, 2021

I agree. In the upgrade guide I was caught off guard, because while I did skim and understand that the advanced regex support has been removed, I expected that this ‘core’ functionality had been left alone. Like @vocko, I see this trailing ? as something you parse using simple string functions and not something that would be affected by removing advanced regex support.

@bluepeter
Copy link

I for one would love to see RegEx support brought back. Related: #7285

@cha0s
Copy link

cha0s commented Mar 16, 2022

Removing regex was a mistake. Whatever survey you did about "usecases", it clearly wasn't broad enough.

"Just write a <Route> for every single possible match!" is an absurd response.

@kulakowka
Copy link

kulakowka commented Mar 16, 2022

I solve this problem like that:

function List() {
  const match1 = useMatch("/items/:id");
  const match2 = useMatch("/items/:id/:tab");

  const id = match1?.params?.id;
  const tab = match2?.params?.tab;
}

<Route path="/items/*" element={<List/>} />

But, it's not good, anywhere.

@cha0s
Copy link

cha0s commented Mar 16, 2022

I'm just doing

useParams().varThatUsedToMatch = 'whatever';

In a root component. This must be what they intended, right? :^)

@pkasarda
Copy link

pkasarda commented Apr 2, 2022

@mjackson please 🙏

@mikegoatly
Copy link

I solve this problem like that:

function List() {
  const match1 = useMatch("/items/:id");
  const match2 = useMatch("/items/:id/:tab");

  const id = match1?.params?.id;
  const tab = match2?.params?.tab;
}

<Route path="/items/*" element={<List/>} />

But, it's not good, anywhere.

Thanks @kulakowka - this was how I ended up having to migrate some of my routes with optional params. The only thing I had to do was make sure that the first match had a wildcard at the end, so that the second parameter could be included without causing it to not match:

  const match1 = useMatch("/items/:id/*");

@Gyran
Copy link

Gyran commented Apr 28, 2022

I've done

<Route path="dashboard" element={<Dashboard />}>
    <Route path="dashboard/:param1" />
    <Route path="dashboard/:param1/:param2" />
    <Route path="dashboard/:param1/:param2/:param3" />
    <Route path="dashboard/:param1/:param2/:param3/:param4" />
  </Route>

Which works but gets the warning

Matched leaf route at location "/dashboard/5" does not have an element. This means it will render an with a null value by default resulting in an "empty" page.

But the Dashboard is rendered rom the parent and it has access to all params so it works :)

@timdorr
Copy link
Member

timdorr commented Nov 2, 2022

This is now superseded by #9546

@timdorr timdorr closed this as completed Nov 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants