router icon indicating copy to clipboard operation
router copied to clipboard

Cannot use `useMatch` in a reuse-able component in multiple routes.

Open MarkLyck opened this issue 2 years ago • 4 comments

Describe the bug

I have a GlobalFilter component that is used on multiple routes.

This filter uses URL search params.

But since useMatch requires a specific routeId I'm forced to give it a single route (even though I re-use the same search params on multiple routes).

I'm not sure it really make sense to give this reuse-able component a single route? But even trying to do so does not seem to work.

if I use my root route for example my GlobalFilter component works fine for the root route /. But when I use it on any other route I get this error:

const { search } = useMatch(indexRoute.id);
Invariant failed: Could not find an active match for "/"!

If I add { strict: false } to it I get both a TypeScript error and the same Invariant error:

const { search } = useMatch(indexRoute.id, { strict: false });
Property 'search' does not exist on type 'RouteMatch<AllRouteInfo<RouteConfig... >
Invariant failed: Could not find an active match for "/"!

Here's a route example:

const indexRoute = rootRoute.createRoute({
  path: '/',
  component: Index,
  validateSearch: z.object({
    test: z.boolean().optional(),
  }),
});

const postsRoute = rootRoute.createRoute({
  path: 'posts',
  component: Posts,
  validateSearch: z.object({
    test: z.boolean().optional(),
  }),
});

Your Example Website or App

https://stackblitz.com/edit/tanstack-router-tkdr9i?file=src/main.tsx

Steps to Reproduce the Bug or Issue

  1. Go to https://stackblitz.com/edit/tanstack-router-tkdr9i?file=src/main.tsx
  2. See error

Expected behavior

I would expect there to be a way to GET and SET search params in a reuse-able component that is used on multiple routes.

Screenshots or Videos

No response

Platform

"@tanstack/react-router": "0.0.1-beta.23",

Additional context

No response

MarkLyck avatar Nov 19 '22 03:11 MarkLyck

Try useNearestMatch() and let me know what you think 😄

tannerlinsley avatar Nov 19 '22 05:11 tannerlinsley

@tannerlinsley

useNearestMatch() seems to work and the component can render fine now.

But I have now lost the TypeSafety :grimacing:

const { search: { selected, resource }, navigate } = useNearestMatch() this will now result in a TypeScript error:

Property 'selected' does not exist on type '{}'
Property 'resource' does not exist on type '{}'

MarkLyck avatar Nov 19 '22 17:11 MarkLyck

I’ll get this fixed

tannerlinsley avatar Nov 19 '22 17:11 tannerlinsley

here's another Stackblitz that reproduces probably a related TS error with navigate({ search }) when using useNearestMatch()

https://stackblitz.com/edit/tanstack-router-af8ox9?file=src/main.tsx

MarkLyck avatar Nov 19 '22 18:11 MarkLyck