Patrick Desjardins Blog
Patrick Desjardins picture from a conference

How to get React Router Route Segment

Posted on: 2018-01-04

Using React-Router library is almost the defacto in the industry right now. It handles many scenarios around how to route and handle URL on the client side. One specific case is that you may have some custom parameter that you want to extract to show specific information. For example, if you have a user and desire to have an url with the user id to load the user's profile when the user visits the URL, the routing system must load the user profile component and let you know which user has been requested.

class Page extends React.Component<PageProps, PageState> { constructor() { super(); }

  public render(): JSX.Element { 
    return <div> 
      <Switch> 
        <Route path={"UserProfile/:userId"} 
          component={UserProfile} /> 
          <Route path="/" component={MainPage} /> 
      </Switch> </div>; 
    } 
} 
const c = connect(mapStateToProps, mapDispatchToProps)(Page); 
export default withRouter(c as any); 

The code above illustrates two routes. The first route is the user profile which takes a user id as part of the url. The second is the default page which doesn't need anything. The challenge is how to get from the UserProfile component the userId. It's easy once you know what will happen. What happens is that the routing library will push a property to the component specified under match. It means that if you are using Typescript that you must specify that member in the property of the component. Let's create a simple user profile component that displays the user id.

class UserProfile extends React.Component<UserProfileProps, {}> {

  public render(): JSX.Element { 
    return <div> <p> User Id # {this.props.match.params.userId} </p> </div>; 
  } 
}

export default connect(mapStateToProps, mapDispatchToProps)(UserProfile); 

The heart of the problem is to have the match member in your property and to do so you need to add manually a match entry and use the "match" class from the definition file of react-router. This one is generic and let you specify which token in the route you want. In our example, it is the user id.

import { match } from "react-router"; 
export interface UserProfileRouteTokens { 
  userId: number; 
} 
export interface UserProfileProps { 
  match: match<UserProfileRouteTokens>; 
} 

This doesn't restrain additional properties, but force you to have one called "match". Back to the component, you can access the segment of the url with auto-complete. From there, you can load the user data by calling a dispatch action or whatever you want to do in that page.