简体   繁体   中英

Multiple Optional Params in React Router

I'm using React Router v5.

I've got a situation where I need to support the following use case.

I've got React component that is accessed via /project/1234 . However, I also need to access this same React component via both /project/1234/hello and /project/1234/goodbye. Again, all three of these routes need to navigate to the same React component.

The following code doesn't work since, as I understand it, if I navigate to /project/1234/goodbye , react-router will interpret this as me passing 'goodbye' as the value of the :hello param, so if I interrogate the params programmatically using react-router's useParams() hook itself, I'll have the wrong param values.

<Route
   path={'project/:context/:hello?/:goodbye?'}
   render={matchProps => <Project {...matchProps}/>}
/>

In other words, if navigate to /project/1234/goodbye and then do:

const params = useParams()
console.log(params.hello)

params.hello will return 'goodbye'

Similarly, this won't work, because using an array, /project/1234/goodbye will always match /project/1234 first, and therefore I won't get any of the params passed through using the useParams() hook that react-router provides.

<Route
   path={['project/:context', 'project/:context/:hello?', 'project/:context/:goodbye?']}
   render={matchProps => <Project {...matchProps}/>}
/>

I could just have:

<Route
   path={'project/:context'}
   render={matchProps => <Project {...matchProps}/>}
/>

However, then when I use react-router's useParams() hook, I won't be able to interrogate the params :goodbye or :hello

Anyone have an idea on how to accomplish this using React Router? Or do I just need to declare separate routes?

UPDATED

This is an updated answer based on a better understanding of the requirements. It appears that you want hello and goodbye to actually be names of URL parameters so that you can grab them in the rendered component.

You have come pretty close to accomplishing this already.

In my example, I will use prameter name var1 (instead of hello or goodbye ) so that by accessing your app using /project/1234/hello you will get {context: "1234", var1: "hello"} and this URI /project/1234/goodbye will yield {context: "1234", var1: "goodbye"}

All you need is this Route:

<Route
      exact
      path={["/project/:context", "/project/:context/:var1"]}
      component={Project}
   />

Then in the rendered component, you can access the URL params like so:

props.match.params

Similarly, this won't work, because using an array, /project/1234/goodbye will always match /project/1234 first, and therefore I won't get any of the params passed through using the useParams() hook that react-router provides.

You are absolutely correct, unless you use the exact param.

Here is a Sandbox: https://codesandbox.io/s/react-router-5-forked-1jjwt?file=/src/index.js

If I understand the question correctly then you can just do:

<Route path="/project/:context">
    <Project />
</Route>

This is because you aren't calling exact path. Basically anything that starts with /project/:context will navigate to the correct component, even if you had 10 more parameters after it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM