DEV Community

Joe Avila
Joe Avila

Posted on

React Router Hook => useParam() (now w/ Typescript)

While working on a project I needed to get some information out of the URL in the browser. Using the URL to declare what to display is a common situation for frontend, client-side rendering. For example, grabbing an ID or username to send to the backend which is the situation for my current project.

I was using class-based React components when I began learning React. Six months later I'm learning the ins and outs of functional components with Hooks to maintain necessary stateful logic without all the extra lifecycle methods. This learning led me to discover the Hooks of React Router.


<Route path={'/quizzes/:id'} render={props => <Quiz {...props}} />

class Quiz extends Component {
   this.state = {
      //necessary state values here
   }

   componentDidMount {
      api.getQuiz(props.match.params.id).then(data =>
         // logic
   )
}
Enter fullscreen mode Exit fullscreen mode

Here's a code snippet from a project I worked on when I first started with React. This Route Path component has parameters that I want to use. While using the render method of Route, I have to destructure or "spread" props inside the component to gain access to the match object.

I declare that anything following the /quizzes/ portion of the Route will be an :id. I pass props into the callback and spread the props object into the Quiz component as outlined by the React Router documentation. All this to gain access to the piece of the URL I need. Now when the user is at myapp.com/quizzes/1 a Quiz component will be rendered. Once this component mounts it will use the 1 from the URL as an ID and make a call to my backend to filter through my Quiz database. If the URL were myapp.com/quizzes/cat then my API call would try using cat as an ID and an error would be sent back from my database. Unless of course, my database contains a quiz with the ID of cat.

Cat Data being sent back

It's worth noting when I wrote the first project I was very new to React and I had been instructed to use the render method to gain access to props. Looking back, I may have been able to make this code less tedious by using the component method of Route where the components already have access to match, history & history as you'll see me do in the next example.

Here is what that same functionality looks like with the useParams() hook.

<Route exact path="/seasons/:id" component={Season} />

const Team = () => {
   const [state, setState] = useState({});
   const { id }= useParams();

   useEffect(() => {
      api.getTeam(id).then(data => {
         //logic 
      }
};
Enter fullscreen mode Exit fullscreen mode

Once again I declare anything following /seasons/ will be an :id. Gaining access to the params is as simple as calling the hook and destructuring the match object, which I know will have a key of id, which points to my value (ie 1 or cat). I don't have to chain calls like in the last example props.match.params.id.

I'm still learning about all the benefits of hooks but I do prefer the look of the code. Thanks for reading, and I'm happy to share my limited knowledge if you have any questions. I'm also very interested in feedback on my use cases.


Update: I've been recently working in typescript. I'm revisiting this article to add how to use this hook with TS. This is assuming you have some basic understanding of Typescript. If you don't, I'd recommend this very basic guide : Typescript for Beginner Programmers by ChibiCode.

In order to useParams you need to implement a generic for useParams. Building on my example above, I need to type the id.


type QuizParams = {
  id: string;
};

// In order to implement that, I'd apply my type to the hook when calling it.

const { id } = useParams<QuizParams>();
Enter fullscreen mode Exit fullscreen mode

Now typescript knows what to expect as a return value from the useParams hook.

Top comments (7)

Collapse
 
surafelgetachew profile image
Surafel Getachew

Thank you for the article, the typescript part helps a lot.

Collapse
 
javila35 profile image
Joe Avila

Thank you.

Collapse
 
tombohub profile image
tombohub

why it doesnt work with interface?

Collapse
 
vcoopman profile image
Vicente Coopman

Thanks for this!

Collapse
 
orxanulfatli profile image
orxanulfatli

why it doesnt work with interface?

Collapse
 
codeddave profile image
David Adeleye

Great article.

Collapse
 
javila35 profile image
Joe Avila

Thank you.