Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make useRouteMatch work with types from react-router

I'm getting the match from my route using the hook like this

const match = useRouteMatch('/chat/:id');

and then I want to pass it down to child component. But when I'm passing it down I'm getting this error

Type 'match<{}> | null' is not assignable to type 'match<MatchParams>'.

In m child component I'm doing this

import { RouteComponentProps } from 'react-router';

interface MatchParams {
  id: string;
}

interface ChildProps extends RouteComponentProps<MatchParams> {}

const Child = ({ match }: ChildProps ): React.ReactElement => {
  return (
    <>
      <div>{match}</div>
    </>
  );
};

export default Child ;

Could someone help me figure out how to type all if this properly please?

like image 828
Person Avatar asked Apr 23 '20 17:04

Person


People also ask

Does react router work with functional components?

Since the introduction of functional components, React has advanced a lot, for example, through the introduction of Hooks. Instead of normal class-based methods, Hooks allow the package to work well with functional components, and many packages are migrating in this direction. As a result, we see React Router Hooks.

What is useroutematch hook in react router?

Before the Hooks are introduced in React router, the component prop in the Route element is one of the methods used to render the components. But we now render them as a child element. And through one of the hooks, we can have access to the match object. This hook is called useRouteMatch. It is also available in the react-router-dom module.

How to create a router in react with react router?

The first thing you’d want to do when creating routing with the React router is to wrap the top-level app, in our case <TodoContainer> element in a router. Here, we introduced our first router component, BrowserRouter. So in the index.js file, import the component from the react-router-dom module.

How to redirect users to another page in react router?

1. useHistory: This is one of the most popular hooks provided by React Router. It lets you access the history instance used by React Router. Using the history instance you can redirect users to another page. The history instance created by React Router uses a Stack (called “History Stack”), that stores all the entries the user has visited.

How do I match a route with a profile in react?

We can use the internal mechanisms of React Router to match any route we want. If we take a look at this top level route, we can see that we want anything that matches /profile to pass on through to our App component. We could theoretically fix this by passing in /profile/:profileId and only rendering if we have an id match.


2 Answers

If you look at the return value of useRouteMatch hook, it can be either of type

match<{}> | null.

useRouteMatch returns null, if the path that you have provided does not match. When you pass it down to the child component, you are sure that it is the correct match but TS is not sure as there was not a check to test for falsey values before passing it down.

The return is of type match and not RouteComponentProps. match is a generic which is empty object by default and this is where the params you expect will go in. To make TS aware you will have to pass this in.

This is how you would have to type it.

Parent.tsx

export interface MatchParams {
  id: string;
}

const match = useRouteMatch<MatchParams>('/chat/:id');

return <Child match={match} />

Child.tsx

import { match } from 'react-router';
import { MatchParams } from './Parent';

interface ChildProps {
  match: match<MatchParams> | null
}

const Child = ({ match }: ChildProps ): React.ReactElement => {
  return (
    <>
      <div>{match}</div>
    </>
  );
};

export default Child ;
like image 130
Sushanth -- Avatar answered Oct 12 '22 03:10

Sushanth --


I believe the whole point of useRouteMatch hook was to avoid passing around match as props.

In case you want to get the match or one of its inner properties (like params) you can use this hook directly in your child.

interface MatchParams {
  id: string;
}

const Child = (): React.ReactElement => {
  const match = useRouteMatch<MatchParams>();

  return (
    <>
      <div>{match}</div>
      <div>{match.params.id}</div>
    </>
  );
};
like image 38
yuval.bl Avatar answered Oct 12 '22 02:10

yuval.bl