React Router 4, How do I get the correct match url using route renderer or Router?

The mapping object that I get using the render property in the Route component or using the HOC from withRouter always creates the wrong mapping object. The location object is correct. The url property matches always "/"

Here is a code pen that shows the React Router 4 problem matches the problems

const { render } = ReactDOM

    const {
      HashRouter,
      Route,
      Link
    } = ReactRouterDOM

    const App = () => (
      <HashRouter>
        <div>
          <AddressBar/>

          <ul>
            <li><Link to="/">Home</Link></li>
            <li><Link to="/about">About</Link></li>
            <li><Link to="/topics">Topics</Link></li>
          </ul>

          <hr/>

          <Route exact path="/" component={Home}/>
          <Route path="/about" component={About}/>
          <Route path="/topics" component={Topics}/>
        </div>
      </HashRouter>
    )

    const Home = () => (
      <div>
        <h2>Home</h2>
      </div>
    )

    const About = ({ match }) => (
      <div>
        <h2>About</h2>
        <h3>Match: {match.url}</h3>
      </div>
    )

    const Topics = ({ match }) => (
      <div>
        <h2>Topics</h2>
        <ul>
          <li><Link to={`${match.url}/rendering`}>Rendering with React</Link></li>
          <li><Link to={`${match.url}/components`}>Components</Link></li>
          <li><Link to={`${match.url}/props-v-state`}>Props v. State</Link></li>
        </ul>

        <Route path={`${match.url}/:topicId`} component={Topic}/>
        <Route exact path={match.url} render={() => (
          <h3>Please select a topic.</h3>
        )}/>
      </div>
    )

    const Topic = ({ match }) => (
      <div>
        <h3>{match.params.topicId}</h3>
        <h3>Match: {match.url}</h3>
      </div>
    )

    const AddressBar = () => (
      <Route render={({ location: { pathname }, match: {url}, goBack, goForward }) => (
        <div className="address-bar">
          <div>
            <button
              className="ab-button"
              onClick={goBack}
            >◀︎</button>
          </div>
          <div>
            <button
              className="ab-button"
              onClick={goForward}
            ></button>
          </div>
          <div className="url">URL: {pathname} Match: {url}</div>
        </div>

      )}/>
    )

    render(<App/>, document.getElementById('root'))

      

Click on the About link (themes have the same issue): note that the AddressBar that uses the route rendering at the top always shows

> Match: /

      

while at the bottom of the screen the Component displays the correct match.url

Match: /about

What am I doing wrong? How do I get a valid match object in the AddressBar?

Here is an ugly hack I used for my specific route where I need to know the specific league parameter.

let keys = []
let path = '/*/:league/:id';
if (this.path.split('/').length === 3)
  path = '/*/:league';
let re = pathToRegexp(path, keys);
const result = re.exec(this.path)
if (result && result[2])
  this.store.setLeague(result[2]);

      

+3


source to share


1 answer


If I understand your question correctly, you want to use React Router's matching tools to infer parameters from a url. This worked for me

import { matchPath } from 'react-router'

const match = matchPath('/users/123', {
  path: '/users/:id',
  exact: true,
  strict: false
})

      



Source: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/matchPath.md

0


source







All Articles