25

I'm trying to build a router link through my application,

In this scenario, I have three files.

App.js

Book.js

DetailedView.js

I have inside of Book built up a <Link> that only appears when hovered ( over a book cover )

{this.state.isHovered ? (
   <Link to={`/details/${this.props.book.industryIdentifiers[1].identifier}`}>
<div className="hover-box"></div>
</Link>) : ( <div /> )}

This will take me to a /details/12345 (isbn10 number)

The thing I have a hard time to understand is how to for example setState({iPressedThisBook}) when pressing <Link> or if i can use the part after /12345 to create like a filter

Because in App the Route will be hooked up as...

<Route path="/details/:id" render={() => (
          <BookDetailedView
            bookStateUpdated = {this.bookStateUpdated}
            book = {this.state.books}
          />
)}/>

I, later on, want to grab the :id so that I make for example a this.props.book.find(:id) inside of my <BookDetailedView>

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
Petter Östergren
  • 973
  • 4
  • 14
  • 27

2 Answers2

44

In order to receive the path param in you component, you need to first connect your component with withRouter HOC from react-router so that you can access the Router props and get the path params from the match props as this.props.match.params.id

Sample Code:

import {withRouter} from 'react-router';

class BookDetailedView extends React.Component {
    render() {
        var id = this.props.match.params.id


    }
}
export default withRouter(BookDetailedView) ;

or simply passing it with render prop in route as

<Route path="/details/:id" render={({match}) => (
          <BookDetailedView
            bookStateUpdated = {this.bookStateUpdated}
            book = {this.state.books}
            id={match.params.id}
          />
)}/>

From the React Documentation of match

match

A match object contains information about how a <Route path> matched the URL. match objects contain the following properties:

  • params - (object) Key/value pairs parsed from the URL corresponding to the dynamic segments of the path
  • isExact - (boolean) true if the entire URL was matched (no trailing characters)
  • path - (string) The path pattern used to match. Useful for building nested s
  • url - (string) The matched portion of the URL. Useful for building nested s

You’ll have access match objects in various places:

  1. Route component as this.props.match
  2. Route render as ({ match }) => ()
  3. Route children as ({ match }) => ()
  4. withRouter as this.props.match
  5. matchPath as the return value

If a Route does not have a path, and therefore always matches, you’ll get the closest parent match. Same goes for withRouter

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • Glad I was able to explain it properly :) – Shubham Khatri Aug 03 '17 at 05:00
  • `this.props.computedMatch.params.id`, I got it from computedMatch – Shan Sep 27 '19 at 12:07
  • Is there a way to access math.params at App level? `matchPath()` seems to be the only way I guess but some of my routes are dynamic hence don't match some path. – sibasishm Apr 08 '20 at 08:21
  • 1
    @SibasishMohanty Please check this post: https://stackoverflow.com/questions/52684017/react-router-v4-nested-match-params-not-accessible-at-root-level/52752990#52752990 – Shubham Khatri Apr 08 '20 at 08:24
  • Thanks. The approach makes sense. I am actually storing some route params in my redux store so that my can access those which is working just fine but I am not sure if this approach of storing routing info in the redux store is the right approach. Your thoughts? @ShubhamKhatri – sibasishm Apr 08 '20 at 08:30
  • 1
    @SibasishMohanty This may not be the best way to handle certain things but with Route params, there is no other way but to lift the state up into a common parent or even a store (flux or redux) to access the values throughout the app – Shubham Khatri Apr 08 '20 at 08:33
  • That's what I was thinking. I will once consider revamping my route structure so that I can work with `matchPath()` else I will stick with the redux approach. – sibasishm Apr 08 '20 at 08:35
-4

You can access :id by doing this.props.params.id

you can handle routing many ways, you don't have to do a you can also handle it in a function .

function doSomethingWhenClicked(id)
{
      doSomething();
      this.props.history.push({
        pathname: '/example/'+id
      });   
      
 }

and bind this function on a onclick element

Zhang Bruce
  • 884
  • 1
  • 8
  • 23