Closed silentworks closed 3 years ago
We already discussed same problem here: https://github.com/AlexxNB/tinro/issues/31
I think to add except
option. Something like this.
<Route path="/map">...</Route>
<Route path="/:username" except="/map">..</Route>
But now it doesn't look flexible.
I don't think except
would be a good option anyway because then you have to state what not to look for. Is this behaviour due to the route inheritance feature? In server-side routers that I've worked within the past, it seems route order is normally how precedence takes place, so if I define /map
path before /:username
then when /map
is matched it will only serve up the route for that and not try to load the route for /:username
.
It turns out that React Router is achieving this by using a special component called Switch
, I'm going to dive into it and see if there is anything that could be useful for tinro. Example below.
<Switch>
<Route exact path='/'>
<Home />
</Route>
<Route path='/map'>
<Topics />
</Route>
<Route path='/:username'>
Hello Person
</Route>
</Switch>
The rule "all matched paths are show" should work, because routes may be in different components and their order may not be clear for programmer. I don't want use exact
keyword, because it describes exact and non-exact routes (/
and /*
).
It may be only
attribute like:
<Route path="/map" only>...</Route>
<Route path="/:username">..</Route>
Internally it is harder to implement than except
option.
Simpler to realize if parent of nested routes will have the option like switch
:
<Route switch>
<Route path="/map">...</Route>
<Route path="/:username">..</Route>
</Route>
Yeah the parent having a switch
would be nice, but after looking through the tinro code I can see it might be a bit hard to implement. But you would know the code better than me so maybe it's not as hard as I'm imagining.
Here is a link to the codesandbox example using the react router that I tested out earlier. Switch only works for the immediate routes and not their children, so if you want the same behaviour for the children you would have to add another Switch component like I did in this example.
Line 136 and 159 is where the switches are.
https://codesandbox.io/s/nested-routes-7-forked-5m8bw?file=/src/App.js
This is also a good breakdown of what happens when using Switch in react-router.
I added firstmatch
option for non-exact route to show only first matched nested route. https://github.com/AlexxNB/tinro#show-first-matched-nested-route-only
I found maybe a better approach:
<script>
import {router,Route} from 'tinro';
let meta = router.meta()
</script>
<Route path="/:username">
{#if $meta.params.username == 'map'}
This is MAP page
{:else}
This is user {$meta.params.username}
{/if}
</Route>
This would not be a better approach since I would have to create this logic inside my routes instead of the router handling it as part of its process.
I currently have a project where I have the following routes
The issue I am currently having is that when a user visits
/map
its also matching with/:username
so I get both routes loading when I think it should have stopped from the first route was matched. I know this has been discussed before and you suggested to change the root level routing to something like/u/:username
, but in a lot of standard web applications you don't need to do this, if you look at Github for example, you can load other routes at the root level while still having access to/:username
. I noticed in react router they solve this with theexact
property on their Route component. I also think react router have a central place (Router component) where route matching happens while it looks like this happens on a per Route component basis with tinro.