darek joda
darek joda

Reputation: 77

router props and custom props with typescript react router dom for functional components

As stated in the title i want to import into my Component react router props and custom props.

My Route looks like this:

<Route
  exact
  path="/logon/:name"
  render={(p)=>(<Content/>)}>
</Route>

Here i get this error: Type '{}' is missing the following properties from type 'CompProps': name, history, location, match

The error comes from my Component which looks like this:

import {RouteComponentProps} from "react-router-dom";

interface CompProps extends RouteComponentProps {
  name: string;
}
export const Content: React.FC<CompProps> = ({
  name,
  match,
}) => {
  return (
    <section>
      <p>test</p>
    </section>
  );
};

Im a beginner to TS, but in my opinion the RouteComponentProps should contain (name, history, location) why it TS throws the error on me. And what is the best practice to pass custom props and Router props to the component?

Here is a screenshot of the error enter image description here

Upvotes: 2

Views: 3613

Answers (3)

tnte
tnte

Reputation: 113

Since "name" is a path-param it should be only accessible via the match object.

You are extending RouterProps with your name-Property. This seems to be okay. But declaring your Functional Component as

export const Content: React.FC<CompProps> = ({
   name,
   match,
}) => {
   ...
}

seems to be wrong. I would expect to define the component as

export const Content: React.FC<CompProps> = (props: CompProps) => {
   const name = props.match.params.name
   return ...;
};

Upvotes: 2

Ethaan
Ethaan

Reputation: 11376

Hmm it seems like what you are doing is correct, can we get a screenshot of the error?

this is what i usually do.

type Props = { id: string };

function Content({ name, match }: RouteComponentProps<Props>) {
  return (
    <section>
      <p>Got match: {match.params.id} on name: {name}</p>
    </section>
  );
}

Change the spread to

render={(p)=>(<Content {...p} name="name" />)}>

does RouteComponentProps already expose name? so you just want to remove it and do

function Content({ name, match }: RouteComponentProps) {
  return (
    <section>
      <p>Got match: {match.params.id} on name: {name}</p>
    </section>
  );
}

Upvotes: 2

superhawk610
superhawk610

Reputation: 2653

When you use Route.render, you need to spread the props that it provides onto your component, otherwise they won't be present when the Content component renders. In your code, change this:

<Route
  exact
  path="/logon/:name"
  render={(p)=>(<Content/>)}>
</Route>

to this

<Route
  exact
  path="/logon/:name"
  render={(p)=>(<Content {...p} />)}>
</Route>

Upvotes: 0

Related Questions