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.