Home > Software design >  get url variables from inside Route
get url variables from inside Route

Time:04-04

Is there a way to get URL variables inside Route's element (and not the component itself), i.e.:

<Route
    path='/book/:id'
    element={<Book data={books[getUrlVarsSomehow().id]} />}
/>

This way, I can pass a single book to Book instead of passing the whole array books and choosing the correct one inside Book, which makes much more sense from a design perspective.

I am using react-router-dom v6.3.0

CodePudding user response:

Yes, create a wrapper component that reads the route params (via useParams hook) and applies the filtering logic and passes the appropriate prop value.

Example:

import { useParams } from 'react-router-dom';

const BookWrapper = ({ books }) => {
  const { id } = useParams();
  return <Book data={books[id]} />;
};

...

<Route
  path='/book/:id'
  element={<BookWrapper books={books} />}
/>

CodePudding user response:

react-router has a hook for that, useParams

Here is an example (from the react-router docs):

https://reactrouter.com/docs/en/v6/examples/route-objects


import { useParams } from "react-router-dom";

function Course() {
  let { id } = useParams<"id">();

  return (
    <div>
      <h2>
        Welcome to the {id!.split("-").map(capitalizeString).join(" ")} course!
      </h2>

      <p>This is a great course. You're gonna love it!</p>

      <Link to="/courses">See all courses</Link>
    </div>
  );
}

Live example: https://stackblitz.com/github/remix-run/react-router/tree/main/examples/route-objects?file=src/App.tsx

CodePudding user response:

Create yourself a wrapping component you can use where ever you might need something from the URL:

import { useParams } from 'react-router-dom'

const WithParams = <T extends Record<string, string>>(props: {
  children: (provided: T) => JSX.Element
}) => <>{props.children(useParams<T>())}</>

// usage

<Route path="/my/path/:someId">
  <WithParams<{someId: string}>>
    {({someId}) => (
      <MyComponent id={someId} />
    )}
  </WithParams>
</Route>

You could create specific versions for specific path params, or create another that uses useLocation.search and parse out URL search param queries as well.

  • Related