preactjs/preact-router

[Question] Is there no way to obtain the values of the URL parameters?

gacardinal opened this issue ยท 3 comments

I've searched around online, in the documentation and in the source code but I can't find any way to access the values of the URL parameters of the current URL that led to the route match from within a component.

What I was hoping for was something akin to [useParams()](https://reactrouter.com/web/example/url-params) hook from react-router.

For example, in this usage example,

import Router from 'preact-router';
import { h, render } from 'preact';
/** @jsx h */

const Main = () => (
  <Router>
    <Home path="/" />
    <About path="/about" />
    // Advanced is an optional query
    <Search path="/search/:query/:advanced?" />
  </Router>
);

render(<Main />, document.body);

How would the Search component be aware of the values of the query and advanced parameters, furthermore, if using typescript, is there a type-safe way to accomplish this?

Am I missing something?

I think this feature is absolutely necessary for many reasons

  • Your components shouldn't have to be aware that the parameters they expect are specifically URL parameters, (IOC)
  • If there is no way to get the parameter values, the rendered components would have to be aware of the current rout match information to be able to parse out the URL into the desired parameters, rendering using this routing package useless

Ty for any pointers!

Here's how I managed to access the URL parameters as props in typescript. However, types don't seem to get enforced.

  1. Use Route with the component prop.
// main.tsx

import { FunctionalComponent, h } from 'preact'
import { Route, Router } from 'preact-router'
// import Search component

const Main: FunctionalComponent = () => {
  return (
    <Router>
      <Route path="/search/:query/:advanced?" component={Search}/>
    </Router>
  )
}
  1. Access URL parameters as props.
// search.tsx

import { FunctionalComponent, h } from 'preact'

type SearchProps = {
  query: string
  advanced: string
}

const Search: FunctionalComponent<SearchProps> = ({ query, advanced }) => {
  ...
}

Hey thanks for your reply, it does make sense to have them as props, but is it me or is it not stated nowhere in the docs?

Maybe it's a bit lacking in that area, but again, maybe I just missed it?

@Gaboik

Handling URLS

๐Ÿ’ Pages are just regular components that get mounted when you navigate to a certain URL. Any URL parameters get passed to the component as props.

Handling URLs

To answer @chandruscm, yes, types cannot be enforced due to the nature of the API here. Maybe you could manipulate template literals to do this, but I'm not really sure. This API isn't the best for TS use as-is (applying path and default props to every child of <Router> is very much not typesafe). <Route> gets around this a bit, but still not ideal