Reputation: 901
Why react router v6 useParams returns object with properties possibly 'undefined'?
In my code below, my IDE indicates const slug: string | undefined
.
const { slug } = useParams<"slug">();
It is because of the Params
type definition:
/**
* The parameters that were parsed from the URL path.
*/
export type Params<Key extends string = string> = {
readonly [key in Key]: string | undefined;
};
But why is not Params
defined like this (without the | undefined
):
export type Params<Key extends string = string> = {
readonly [key in Key]: string;
};
If a route with a parameter matches the URL then the parameter cannot be undefined
. So, is there any case when useParams
returns with an undefined
param?
Upvotes: 24
Views: 24722
Reputation: 91
In my case, I simply wanted the id
passed in via the React router path:
<Route path="/person/:id" element={<UpdatePerson />} />
I couldn't figure out a one-liner, so ended up settling for:
let { id } = useParams();
id = id as string;
Upvotes: 0
Reputation: 61
One workaround is to extend module and change the desired type.
Create src/react-router-dom.d.ts
file with content:
import 'react-router-dom';
declare module 'react-router-dom' {
export declare function useParams<
ParamsOrKey extends string | Record<string, string | undefined> = string,
>(): { [key in ParamsOrKey]: string };
}
Upvotes: 6
Reputation: 59336
I believe this is a questionable design choice. React Router 6 doesn't support optional parameters, so there is no apparent reason, but even if it did support, it should be responsibility of the user to determine which parameters are optional.
One way to go around it is:
export type MyParams = {
a: string;
b: string;
c: string;
};
const { a, b, c } = useParams<keyof MyParams>() as MyParams;
Upvotes: 34
Reputation: 202856
Route params can be possibly undefined if the path has no defined parameters.
Example: "/path/to/page"
There are no route match params to access.
If you were to attempt to access a param
const { id } = useParams();
then id
is of course, undefined.
Upvotes: 12