Coder Social home page Coder Social logo

Comments (12)

chungweileong94 avatar chungweileong94 commented on May 21, 2024 2

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;
};

from router.

joshuabrokaw avatar joshuabrokaw commented on May 21, 2024

If you look at the API reference, there's another hook useMatches link

this should give you what you are looking for.

happy hacking!

from router.

chungweileong94 avatar chungweileong94 commented on May 21, 2024

If you look at the API reference, there's another hook useMatches link

this should give you what you are looking for.

happy hacking!

I did try the useMatches, however, it only returns one match for some reason🤔

from router.

chungweileong94 avatar chungweileong94 commented on May 21, 2024

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 />},

from router.

joshuabrokaw avatar joshuabrokaw commented on May 21, 2024

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>();

from router.

chungweileong94 avatar chungweileong94 commented on May 21, 2024

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.

from router.

joshuabrokaw avatar joshuabrokaw commented on May 21, 2024

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;
};

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.

from router.

chungweileong94 avatar chungweileong94 commented on May 21, 2024

@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

from router.

joshuabrokaw avatar joshuabrokaw commented on May 21, 2024

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.

from router.

chungweileong94 avatar chungweileong94 commented on May 21, 2024

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.

from router.

tannerlinsley avatar tannerlinsley commented on May 21, 2024

from router.

chungweileong94 avatar chungweileong94 commented on May 21, 2024

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👍

from router.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.