preactjs / preact-router

:earth_americas: URL router for Preact.
http://npm.im/preact-router
MIT License
1.02k stars 155 forks source link

Expose matchPath logic for server side rendering #220

Open brunoscopelliti opened 7 years ago

brunoscopelliti commented 7 years ago

I'm trying to setup an isomorphic preact app, that uses preact-router.

I'm new to preact, but I've worked with react, and react-router before.

I'm trying to replicate with preact, and preact-router the data loading use case, but I'm blocked because preact does not export the method it uses internally to find the matching route.

On the contrary react-router exports the matchPath method.

Naturally preact-router has already all the building pieces of a such method, it only has to export it. I'm thinking at something like:

interface IRoute{
  attributes: IRouteAttribute
  path: string
}

interface IRouteAttribute{
  default: boolean,
  path: string
}

function getMatchingRoute(routes: IRoute[], currentRoute:string) : IRoute|null {} 

But of course any suggestion is welcome. I've also sketched an implementation, that in my tests works fine:

// pathRankSort, and exec are defined in preact-router/utils

const getMatchingRoute =
  (routes, currentRoute) => {
    return routes
      .sort(pathRankSort)
      .find((route) => !!exec(currentRoute, route.attributes.path, route.attributes)) || null;
  };

Any thoughts on this? Am I missing the obvious way to achieve what I'm trying to do?

If on the contrary there's interest in a such functionality to be exposed by preact-router I can submit a proper PR in the next days.

brunoscopelliti commented 7 years ago

At the moment in order to achieve my use case I'm using the following:

import Router from "preact-router";
const getMatchingRoute = Router.prototype.getMatchingChildren;

const route = getMatchingRoute(routes, currentUrl, false);

... but I'm not sure it's the best approach, because:

developit commented 7 years ago

Unlike react-router, this router doesn't work outside the confines of Virtual DOM - if you want to render a match for a route you need to render a router with that URL:

<Router url="/profile/john">
  <Home />
  <MyProfile path="/profile" />
  <Profile path="/profile/john" />
</Router>

Based on this and your other comment, it sounds like you should be using react-router, not preact-router: due to the naming it's common to confuse preact-router for "a preact version of react-router", but really it's nothing like react-router at all - it's just a general purpose routing component structure for Preact. React Router 3 and prior work great with preact-compat, or if you're using React Router v4, that works out-of-the-box with Preact itself (no compat).

Regarding the new method, I'm happy to export any of the internals that would make your use-case possible, just keep in mind this library doesn't aim to replicate react-router's API or functionality at all.

brunoscopelliti commented 7 years ago

Thanks @developit for your reply. I'm not sure what you mean here

Unlike react-router, this router doesn't work outside the confines of Virtual DOM

... and I'll appreciate further explanation.

you should be using react-router, not preact-router

I've considered it, but at the moment I prefer a preact-pure approach for different reasons.

I'm happy to export any of the internals that would make your use-case possible

Glad to hear this. In the next days I'm going to open a pull request, and write a document to illustrate better my use case... Then you'll be in a better position to decide if you want this in preact-router.

Even if preact-router's aim is not to replicate react-router's functionality, I think that exporting internal logic unit makes possible to developers, to do just that in user-code land.

brunoscopelliti commented 7 years ago

I've just opened the pull request #222. I hope I've explained a little better my use case in the pull request itself. @developit please let me know what you think, and if there is anything else I can do. Thanks.

developit commented 7 years ago

I like the idea, will reivew.

vpzomtrrfrt commented 1 year ago

Looks like getMatchingRoutes has since been removed, is there an intended replacement?