Stupid.Fat.Cat
Stupid.Fat.Cat

Reputation: 11295

How do you get the path in a ReactJS HashRouter constructed URL?

I have the following

class EntityProfile extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        console.log(this.props.location) // This doesn't work
        console.log(window.location.hash.split('/')[2], 'this is my id')
        return (
            <Container fluid>
                <Row>
                    <span>hiiii</span>
                    <span>{this.props.location}</span>
                </Row>
            </Container>
        );
    }
}

And they're all within a HashRouter, there is one route in specific that looks like so:

                    <Route path="/foo/:id">
                        <FooBar/>
                    </Route>

And I want to get the "id" from that. I read that you can use this.props.location that appears to be undefined, I could get it using window.location.hash.split('/')[2] but that seems a bit dodgy. My uri looks like so: http://localhost:5000/#/foo/1, so in this case I would like to get 1. What am I doing wrong with he location value?

Upvotes: 2

Views: 1354

Answers (1)

Drew Reese
Drew Reese

Reputation: 202686

Issue

The route props (history, location, and match) are only passed to a rendered component via the route render methods.

Route render methods

The recommended method of rendering something with a <Route> is to use children elements, as shown above. There are, however, a few other methods you can use to render something with a <Route>. These are provided mostly for supporting apps that were built with earlier versions of the router before hooks were introduced.

  • <Route component>
  • <Route render>
  • <Route children> function

Rendering children components just isn't enough to get the route props.

<Route path="/foo/:id">
  <FooBar /> // <-- no route props
</Route>

Solution

For the given path path="/foo/:id" the id param will actually be on the match object.

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 <Route>s
  • url - (string) The matched portion of the URL. Useful for building nested <Link>s

Here are several methods for accessing the params object.

  1. Render via the component prop and access via props.match.params.id.

    <Route
      path="/foo/:id"
      component={FooBar}
    />
    
  2. Render via the render prop and access via props.match.params.id.

    <Route
      path="/foo/:id"
      render={(props) => <FooBar {...props} />}
    />
    
  3. If child is functional component use the useParams React hook.

    const { id } = useParams();
    
  4. Decorate the component with the withRouter Higher Order Component and access via props.match.params.id.

    default export withRouter(FooBar);
    

    ...

    <Route path="/foo/:id">
      <FooBar /> // <-- decorated component will receive route props
    </Route>
    

Upvotes: 1

Related Questions