3

I'm using a simple router in React

  <Router>
    <div>                   
       <Switch>
         <Route path="/" component={ Home } exact /> 
         <Route path="/contact" component={ Contact } />   
         <Route path="/:slug" component={ Post } />                       
        </Switch> 
    </div>
  </Router>

I'm pulling posts from a blog using REST and have a router component named Post for single blog posts. Any Route that doesn't match with home or contact, uses the post component.

How can I get or pass the route slug/url segment in the Post component? For example if the url segment/slug is /some-blog-post-title, I want to retrieve it, preferably using a React Router function/method if it exists.

2 Answers 2

5

You can get the parameters in the props.match.params object. To get your :slug parameter you would write props.match.params.slug.

Example

class Post extends React.Component {
  componentDidMount() {
    this.getPost(this.props.match.params.slug);
  }

  componentDidUpdate(prevProps) {
    if (prevProps.match.params.slug !== this.props.match.params.slug) {
      this.getPost(this.props.match.params.slug);
    }
  }

  getPost = slug => {
    // ...
  };

  render() {
    return <h2>{this.props.match.params.slug}</h2>;
  }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you! This works! The only problem is that the Post route is being ignored in the router switch if added below other routes with specific components. If I add it above them it works but the routes below are ignored. I tried adding exact but does not make a difference..
@CyberJunkie You're welcome! I'm not quite sure I understand. The switch makes sure that only one Route in the Switch is rendered. Since path="/:slug" work as a wildcard for all routes, you can't have e.g. /contact below it since that would fit inside /:slug.
I placed /contact above the wildcard route and it is being rendered but then the wildcard route is not when going to a custom/dynamic path. I have routes with specific components for paths like /contact and one component for wildcard paths. I'm not sure how to make both work.
@CyberJunkie What you have written in your question should work. You might have duplicate Router components, or there might be something else that is causing that behavior.
If this yields undefined, you can use the HOC withRouter such as: import { withRouter } from "react-router-dom";, then, const PostWithRouter = withRouter(Post); This wuld give you access to the this.props.match property
5

If you want to grab urls in a functional component

App.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import User from './User';
class App extends Component {
    render() {
        return (
            <Router>
                <Switch>
                    <Route exact path='/user/:userName' component={User} />
                    <Route>
                        <div>Default page</div>
                    </Route>
                </Switch>
            </Router>
        );
    }
}
export default App;

Inside the functional component you can grab it

import React from 'react';
import { useParams } from 'react-router-dom';
const User = () => {
    const { userName } = useParams();
    return (
        <div>Username: { userName }</div>
    );
}
export default User;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.