Coder Social home page Coder Social logo

Comments (14)

omgovich avatar omgovich commented on May 1, 2024

Hi @cbbfcd. I just checked out the react-router docs/demos and found out that they use the same approach where order matters. So we probably shouldn't change anything in code.

from wouter.

molefrog avatar molefrog commented on May 1, 2024

Hey guys! I think we should definitely implement support for default prop since a lot of people were asking about that and not everyone gets the :rest* trick — it's just not developer-friendly.

Should the order matter is a good question. Rather than copying it 1-1 from react-router I would first think about possible design choices we would need to make in both cases.

Let's say the order doesn't matter. Can the Switch then have multiple default routes? I think it can, it's valid, although not a very practical scenario. In this case which one gets rendered: first one, second or both?

On the other hand, we can just say that default Route is a Route that always matches in a Switch. In this case this:

<Switch>
  <Route default>foo!</Route>
  <Route path="/app">app</Route>
  <Route default>Second default!</Route>
</Switch>

Would always render foo! no matter what (even if the location is /app). And it fits better with the Switch contract "only one child is renderer at most at the time".

from wouter.

molefrog avatar molefrog commented on May 1, 2024

To recap.
Position-independent default Route:
✔️Possible better DX, although breaks the common "catch-all" mental model from server-side routing
❓Isn't clear how it should behave in edge cases
❓Probably harder to implement and is size-consuming: will need to make an extra iteration over children to determine the first default route

Position-dependent default Route:
✔️Follows the same mental model used in RR and server-side routing (Rails, Express, Sinatra etc.)
✔️Doesn't break the Switch contract:
✔️Should be relatively easy to implement — add an extra check here:

-      (match = matcher(element.props.path, location || originalLocation))[0] 
+      (element.props.default || (match = matcher(element.props.path, location || originalLocation))[0] 

So, I would go with the latest. Let me know what you think!

from wouter.

omgovich avatar omgovich commented on May 1, 2024

@molefrog I like the Position-dependent default Route option.
But I think that most of the users won't understand that default means.
Probably they're looking for 404 or fallback route.

Also I guess that we should keep in mind common practices that developers used to.
So I have two options to discuss.

1. Route without path

Instead of defining the new param, just use the same approach as react-router.

Routes without a path always match (react-router docs)

<Switch>
  <Route path="/">Home</Route>
  <Route path="/app">App</Route>
  <Route>404</Route>
</Switch>
-      (match = matcher(element.props.path, location || originalLocation))[0] 
+      (!element.props.path || (match = matcher(element.props.path, location || originalLocation))[0] 

2. Route with path="*"

This is the way to setup default route in vue-router.
And it works in react-router as well.
I guess this is the way that users expect.

<Switch>
  <Route path="/">Home</Route>
  <Route path="/app">App</Route>
  <Route path="*">404</Route>
</Switch>

We could just change this line:

-      (match = matcher(element.props.path, location || originalLocation))[0] 
+      (element.props.path === "*" || (match = matcher(element.props.path, location || originalLocation))[0] 

... or update the matcher.

from wouter.

cbbfcd avatar cbbfcd commented on May 1, 2024

Hey guys! I think we should definitely implement support for default prop since a lot of people were asking about that and not everyone gets the :rest* trick — it's just not developer-friendly.

Should the order matter is a good question. Rather than copying it 1-1 from react-router I would first think about possible design choices we would need to make in both cases.

Let's say the order doesn't matter. Can the Switch then have multiple default routes? I think it can, it's valid, although not a very practical scenario. In this case which one gets rendered: first one, second or both?

On the other hand, we can just say that default Route is a Route that always matches in a Switch. In this case this:

<Switch>
  <Route default>foo!</Route>
  <Route path="/app">app</Route>
  <Route default>Second default!</Route>
</Switch>

Would always render foo! no matter what (even if the location is /app). And it fits better with the Switch contract "only one child is renderer at most at the time".

Yep! I just have this idea. I mentioned a related PR before, but I think I can have a better implementation.i will try

from wouter.

cbbfcd avatar cbbfcd commented on May 1, 2024

@molefrog I like the Position-dependent default Route option.
But I think that most of the users won't understand that default means.
Probably they're looking for 404 or fallback route.

Also I guess that we should keep in mind common practices that developers used to.
So I have two options to discuss.

1. Route without path

Instead of defining the new param, just use the same approach as react-router.

Routes without a path always match (react-router docs)

<Switch>
  <Route path="/">Home</Route>
  <Route path="/app">App</Route>
  <Route>404</Route>
</Switch>
-      (match = matcher(element.props.path, location || originalLocation))[0] 
+      (!element.props.path || (match = matcher(element.props.path, location || originalLocation))[0] 

2. Route with path="*"

This is the way to setup default route in vue-router.
And it works in react-router as well.
I guess this is the way that users expect.

<Switch>
  <Route path="/">Home</Route>
  <Route path="/app">App</Route>
  <Route path="*">404</Route>
</Switch>

We could just change this line:

-      (match = matcher(element.props.path, location || originalLocation))[0] 
+      (element.props.path === "*" || (match = matcher(element.props.path, location || originalLocation))[0] 

... or update the matcher.

👍

from wouter.

cbbfcd avatar cbbfcd commented on May 1, 2024

reach/router Breaking some routines, I think the effect is not bad.

from wouter.

cbbfcd avatar cbbfcd commented on May 1, 2024

Matching the first one is accepted by most people. Following this pattern, Position-dependent may be better, but using /:any* is really confusing, I prefer default or evev no path attribute....

from wouter.

molefrog avatar molefrog commented on May 1, 2024

Same here, position-dependent with no path sounds like an ideal option.

from wouter.

cbbfcd avatar cbbfcd commented on May 1, 2024

i will make a PR later !!! 😂

from wouter.

cbbfcd avatar cbbfcd commented on May 1, 2024

@molefrog @omgovich

in Route:

const [matches, params] = match || useRouteMatch;

so

(!element.props.path || (match = matcher(element.props.path, location || originalLocation))[0] 

if we don't have a path prop, the match will be 0,and this will cause a trouble.
if i fixed the problem with:

((match = [!element.props.path])[0] ||
(match = matcher(element.props.path, location || originalLocation))[0])

i can pass all the unit test, but the size limit(+10b), and i think this solution is ugly.
so, do you hava any suggestions?

from wouter.

molefrog avatar molefrog commented on May 1, 2024

Would something like this work:

if (
  isValidElement(element) &&
  // 1. If `path` is present — match against it
  // 2. No `path` — use always positive match
  (match = element.props.path
    ? matcher(element.props.path, location || originalLocation)
    : [true, {}])[0]
)

from wouter.

cbbfcd avatar cbbfcd commented on May 1, 2024

looks great! The main problem now is the size limit, let me think about it.

from wouter.

molefrog avatar molefrog commented on May 1, 2024

@cbbfcd Hey, the feature has finally landed in the new release: https://github.com/molefrog/wouter/releases/tag/v2.5.0

Thanks again for your awesome work on the feature!

from wouter.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.