5

In react router v6, how can I pass route params to a component without the need to use useParams() in the component?

This is what I want to do:

<Route
  path='/'
  element={ProfileComponent username={'thedefault'}
/>
<Route
  exact
  path='/u/:username/'
  render={(props) => 
    <ProfileComponent username={props.match.params.username}/>
  }
/>

I don't want to put useParams() in the component because this tightly couples it to the URL. For example, what if I wanted to render another ProfileComponent elsewhere, with a different username to that in the URL. It seems to violate best practice for unit testing unless I can do it like my example.

ServerBloke
  • 802
  • 3
  • 15
  • 24

2 Answers2

10

I don't want to put useParams() in the component because this tightly couples it to the URL. For example, what if I wanted to render another ProfileComponent elsewhere, with a different username to that in the URL. It seems to violate best practice for unit testing unless I can do it like my example.

Any route using a username route match param would still be accessible via the useParams hook, but I think I understand what you are after. If I understand your question correctly you are asking how to map a route match param to a component prop in a generic way.

For this you can simply use a wrapper component to "sip" the route match param and pass it along to your component on any specific prop.

const ProfileComponentWrapper = () => {
  const { username } = useParams();
  return <ProfileComponent username={username} />;
};

...

<Route
  path='/u/:username/'
  element={<ProfileComponentWrapper />}
/>
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
2

In the docs, it is clearly specified that it is not possible

Normally in React you'd pass this as a prop: , but you don't control that information because it comes from the URL.

https://reactrouter.com/docs/en/v6/getting-started/tutorial#reading-url-params

So, you have to use useParams in the component

eneski
  • 1,575
  • 17
  • 40