-
-
Notifications
You must be signed in to change notification settings - Fork 10.4k
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
Accept array of strings in route path #5393
Conversation
Like I said in #4159, it is not as simple as that. While we do pass the path prop directly into path-to-regexp, we also use it to determine the URL for the match. This would only be acceptable if there was a failing test added on the match's URL and a fix implemented for that failure. |
@timdorr ah I missed that stuff on line 48. We have added some test cases now for the path as array case, however to make the tests pass we had to remove the path === '/' that happened on line 48. var pathToRegexp = require("path-to-regexp")
const re = pathToRegexp(['/somewhere', ''], { end: false })
console.log(re.exec("/elsewhere/else"))
// => [""] so in this case url is empty "" but there was a match, so that must mean that the path was either "/" or "", which feels safe to set the url to "/", but maybe you have more insight? thanks! |
Any update on this? Would love to see this get merged. 🙏 |
@timdorr if there's more work to do for this, happy to chip in. |
The reason that this isn't currently done has more to do with there not being a compelling reason than with difficulty in implementing it (since there really isn't any), so any work required to get this merged is in convincing Ryan/Michael that <Route path={[ '/one', '/two' ]} component={Thing} /> is significantly better than <Route path='/one' component={Thing} />
<Route path='/two' component={Thing} /> |
Thanks @pshrmn okay I will explain why we need this feature (it will fix an issue we currently have on one of our sites in prod): So it isn't that : <Route path={[ '/one', '/two' ]} component={Thing} /> Is any better than: <Route path='/one' component={Thing} />
<Route path='/two' component={Thing} /> It's that the first example will not cause a Unmount and then a Mount of the This is an issue for us because we have some slightly complex route changes that will change the url but not the content on the page, and we are currently using the From what I've seen in the issues linked above, it looks like others also have noticed this and would benefit from this simple change! Happy to help in anyway to continue this discussion :) cc @timdorr |
Inside of a |
Thanks for the info and great example @pshrmn So i've looked at our code and it was wrapped by the If you take a look at the main function in that package: renderRoutes.js We traced this down to the following: the I've modified your example to show this in a small test case: Notice how the Im not sure why this is happening, but if we can figure this out then maybe this PR is not needed to do what we want :) Thanks again! |
...but it is needed to cover cases where The docs expressly encourage composing routes in a bunch of different ways...
It feels a bit meh that this
and this
happen to be equal if your application fits Isn't it much cleaner to be able to say It's just one merge away... 🤞 |
This isn't my call to make. Ryan/Michael are the ones that will have to make this decision (but please don't ping them, they can see all of the PRs here and will get to this eventually). Based on past rejections of the same request, I would say that this is unlikely to be added, but I won't dismiss it altogether. |
For most people who have this problem (want to render the same component at 2 different paths) I'd say they should just map over the array and render 2 But if you want to avoid re-mounting the component when the location changes, it's a little more tricky because you'll need to re-use the same Of course, at some point in your logic you're going to have to differentiate between the paths and do something like: if (location.pathname === '/one') {
// do something for /one...
} else if (location.pathname === '/two') {
// do something for /two...
} Would that work for your use case, @Shervanator? |
Very much looking forward to this being merged in. |
Also would want this merged. |
Me too. @Shervanator are you still with us? :) |
I see the way to work around the problem, but there's seem no clear reason to not merge it 🤔 |
I also like to see it merged. But if not, the docs should be adapted: https://reacttraining.com/react-router/web/api/Route/path-string
In fact, that's currently not true! So at this point there should be a hint that only strings are accepted. |
I have the same use case described above as well as in 4551. That is, multiple exact routes should render the same component, and I do NOT want the component to re-mount when the location changes between acceptable routes. As vuhrmeister mentioned, the docs explicitly state that I can use any path that path-to-regexp understands - which as it currently stands is incorrect. The implication is that I've spent too much time trying to figure out what I'm doing wrong, when in fact the documentation itself is wrong. I'd really like to see this PR merged, but at the very least, I'd much appreciate if the docs could be adjusted to explain that only strings are permitted. |
I just want to add that having to re-mount the component is really ugly, for instance, if you are using route transitions and can also have a lot of other side effects... I'd really love to see this merged in. |
What remains to be done to see this PR merged ? |
I'm not totally opposed to the idea of For example, if you wanted to build a relative <Route path="/users/:id" render={match => (
<Route path={`${match.path}/profile`} ... />
)}> This would create 2 routes: one at <Route path={[ '/one/:id', '/two/:id' ]} render={match => (
<Route path={`${match.path}/profile`} ... /> // boom! :/
)}> So unfortunately I can't just merge this change as it stands. I'll update the docs so people know that we only accept strings there, but I'm open to ideas about how this could be improved in the future. Thanks everyone for the discussion! |
@mjackson With your code, you can't do the same thing for two differents path : If you use two |
@mjackson I tried to reproduce your example... The problem is that, using Array, the React DOM tree is rendered like this (from React dev tools) <Route path={[ '/users/:id', '/people/:id' ]} render=render()>
<Route path='/users/:id,/people/:id'/profile' render=render()/></Route>
</Route> If the props returned from match where coherent, that is Array --> Array and String --> String instead of having Array --> Array.join(',') and String --> String then it could work See the code here https://stackblitz.com/edit/react-j6qceq?embed=1&file=BasicExample.js |
You can avoid this with the |
@timdorr Can you provide me an example ? I've tested
and MyComponent is remount everytime I switch betwenn /foo and /test |
I think you're right, @lamuertepeluda. I've opened #5866 to track this work. As long as we can make sure that |
I just tried
also works option |
This line of code work fine, but it still has the following warning in the console
I am using version 4.3.1. |
The
path-to-regexp
library supports an array of strings as a pattern, however we are getting PropTypes warnings about this. This PR enables support for this.It seems like we do not touch the path and just pass it on to the
path-to-regexp
library directly.See these previous PR's and Issues for more context:
#4159
#4551