Closed chungweileong94 closed 2 years ago
If you look at the API reference, there's another hook useMatches
link
this should give you what you are looking for.
happy hacking!
If you look at the API reference, there's another hook
useMatches
linkthis should give you what you are looking for.
happy hacking!
I did try the useMatches
, however, it only returns one match for some reason🤔
So I didn't realize that the order of the routes does matter, which makes sense. For instance,
// This won't work
{path: '/post/:postId', element: <Page />},
{path: '/post/:postId/comment/:commentId', element: <Page />},
// This works
{path: '/post/:postId/comment/:commentId', element: <Page />},
{path: '/post/:postId', element: <Page />},
I personally find that the useMatches
is quite difficult to use in scenarios like if I want to get all the match params.
It would be great if we have something like const params = useParams()
.
As for now, I created a custom hook to merge all the match params from useMatches
, it feels hacky, but works for me
export const useParams = <TGenerics extends PartialGenerics = DefaultGenerics>() => {
const matches = useMatches<TGenerics>();
const params = useMemo(
() =>
matches.reduce((result, match) => {
return {...result, ...match.params};
}, {} as TGenerics['Params']),
[matches],
);
return params;
};
do you have your MakeGenerics
setup?
pulled from the Kitchen Sink example.
export type LocationGenerics = MakeGenerics<{
Params: {
postId: string;
commentId: string;
};
}>;
const location = new ReactLocation<LocationGenerics>();
const routes: Route<LocationGenerics>[] = [
...
{path: '/post/:postId/comment/:commentId', element: <Page />},
{path: '/post/:postId', element: <Page />},
...
];
With that setup are you still not able to do this?
const { params: { postId, commentId }} = useMatch<LocationGenerics>();
do you have your
MakeGenerics
setup?pulled from the Kitchen Sink example.
export type LocationGenerics = MakeGenerics<{ Params: { postId: string; commentId: string; }; }>; const location = new ReactLocation<LocationGenerics>(); const routes: Route<LocationGenerics>[] = [ ... {path: '/post/:postId/comment/:commentId', element: <Page />}, {path: '/post/:postId', element: <Page />}, ... ];
With that setup are you still not able to do this?
const { params: { postId, commentId }} = useMatch<LocationGenerics>();
Not sure if I understand you correctly, but MakeGenerics
or TypeScript in general, has nothing to do with the problem that I was facing. in fact, it was caused by the order of how I define the routes.
I personally find that the
useMatches
is quite difficult to use in scenarios like if I want to get all the match params. It would be great if we have something likeconst params = useParams()
.As for now, I created a custom hook to merge all the match params from
useMatches
, it feels hacky, but works for meexport const useParams = <TGenerics extends PartialGenerics = DefaultGenerics>() => { const matches = useMatches<TGenerics>(); const params = useMemo( () => matches.reduce((result, match) => { return {...result, ...match.params}; }, {} as TGenerics['Params']), [matches], ); return params; };
I was referencing what you said here. If you have your MakeGenerics
setup, you should be able to pull off all the params, without having to write a custom hook.
@joshuabrokaw I see.
useMatches
does work, but it returns an array like
[
{
// ...
params: {postId: 1},
},
{
// ...
params: {postId: 1, commentId: 2},
},
];
Which means I have to search through the array and extract the params I need (in this case, I need both postId
& commentId
).
So I create a custom hook just to to extract and merge all the params
Yeah, my point is that you don't have to do that, if you setup your MakeGenerics
like in the example I showed you.
Do you have MakeGenerics
setup? You won't need to merge them all together like that if you do.
Assuming your routes are ordered correctly.
Yeah, my point is that you don't have to do that, if you setup your
MakeGenerics
like in the example I showed you.Do you have
MakeGenerics
setup? You won't need to merge them all together like that if you do.
Hmm, I understand that, but from what I know MakeGenerics
is just a type. The problem I was facing will happen on both JavaScript & TypeScript, setup the MakeGenerics
won't magically merge them all.
For Example:
export type LocationGenerics = MakeGenerics<{
Params: {
postId: string;
commentId: string;
};
}>;
const location = new ReactLocation<LocationGenerics>();
const routes: Route<LocationGenerics>[] = [
...
{path: '/post/:postId/comment/:commentId', element: <Page />},
{path: '/post/:postId', element: <Page />},
...
];
...
// Let say the route is "http:locahost:3000/post/1/comment/2"
const matches = useMatches<LocationGenerics>();
The matches
will be an array of all match results, that's why I still have to search through the array to get the correct match that contains the params I want
[
{
// ...
params: {postId: 1},
},
{
// ...
params: {postId: 1, commentId: 2},
},
];
If I use useMatch
, it will return
{
// ...
params: {postId: 1},
},
Which is definitely not something I want to use.
Why won’t useMatch().params not work? They are merged down the match tree to include parent params.
Tanner Linsley On Dec 23, 2021, 9:50 AM -0700, Chung Wei Leong @.***>, wrote:
Yeah, my point is that you don't have to do that, if you setup your MakeGenerics like in the example I showed you. Do you have MakeGenerics setup? You won't need to merge them all together like that if you do. Hmm, I understand that, but from what I know MakeGenerics is just a type. The problem I was facing will happen on both JavaScript & TypeScript, setup the MakeGenerics won't magically merge them all. For Example: export type LocationGenerics = MakeGenerics<{ Params: { postId: string; commentId: string; }; }>;
const location = new ReactLocation
(); const routes: Route
[] = [ ... {path: '/post/:postId/comment/:commentId', element: }, {path: '/post/:postId', element: }, ... ]; ...
// Let say the route is "http:locahost:3000/post/1/comment/2" const matches = useMatches
(); The matches will be an array of all match results, that's why I still have to search through the array to get the correct match that contains the params I want [ { // ... params: {postId: 1}, }, { // ... params: {postId: 1, commentId: 2}, }, ]; If I use useMatch, it will return { // ... params: {postId: 1}, }, Which is definitely not something I want to use. — Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android. You are receiving this because you are subscribed to this thread.Message ID: @.***>
Why won’t useMatch().params not work? They are merged down the match tree to include parent params. Tanner Linsley … On Dec 23, 2021, 9:50 AM -0700, Chung Wei Leong @.>, wrote: > Yeah, my point is that you don't have to do that, if you setup your MakeGenerics like in the example I showed you. > Do you have MakeGenerics setup? You won't need to merge them all together like that if you do. Hmm, I understand that, but from what I know MakeGenerics is just a type. The problem I was facing will happen on both JavaScript & TypeScript, setup the MakeGenerics won't magically merge them all. For Example: export type LocationGenerics = MakeGenerics<{ Params: { postId: string; commentId: string; }; }>; const location = new ReactLocation
(); const routes: Route @.>[] = [ ... {path: '/post/:postId/comment/:commentId', element: }, {path: '/post/:postId', element: }, ... ]; ... // Let say the route is "http:locahost:3000/post/1/comment/2" const matches = useMatches (); The matches will be an array of all match results, that's why I still have to search through the array to get the correct match that contains the params I want [ { // ... params: {postId: 1}, }, { // ... params: {postId: 1, commentId: 2}, }, ]; If I use useMatch, it will return { // ... params: {postId: 1}, }, Which is definitely not something I want to use. — Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android. You are receiving this because you are subscribed to this thread.Message ID:
Uh my bad, you are right, I'm actually confused by my current code setup. Yeah, it works as expected now👍
Describe the bug If my URL contains more than one param like
/menu/:menuId/sub/:subId
,useMatch
will only returnmenuId
when the route is match. I also useuseMatchRoute
to make sure that the route is really matches.To Reproduce Steps to reproduce the behavior:
/menu/:menuId/sub/:subId
useMatch
useMatch
Expected behavior The
useMatch
should return bothmenuId
&subId
Screenshots
Desktop (please complete the following information):