score:117

Accepted answer

if you want to pass props to a component inside a route, the simplest way is by utilizing the render, like this:

<route exact path="/details/:id" render={(props) => <detailspage globalstore={globalstore} {...props} /> } />

you can access the props inside the detailpage using:

this.props.match
this.props.globalstore

the {...props} is needed to pass the original route's props, otherwise you will only get this.props.globalstore inside the detailpage.

score:0

try this.

<route exact path="/details/:id" render={(props)=>{return(
    <detailspage id={props.match.params.id}/>)
}} />

in details page try this...

this.props.id

score:0

simple example with class, hoc and router v5

package.json

"react-router-dom": "5.3.1",
"react-router": "5.3.1",
"@types/react-router-dom": "5.3.3",
// yourcomponent.tsx

import react from 'react';
import { routecomponentprops, withrouter } from 'react-router';

export interface pathparams {
    id: string;
}

export interface props extends routecomponentprops<pathparams> {}
export interface state {}

class yourcomponent extends react.component<props, state> {
    constructor(props: props) {
        super(props);
        this.state = {};

        console.log(props.match.params) // { id: 1 }
        // typescript completions
        console.log(props.match.params.id) // 1
    }

    render() {
        return <></>;
    }
}

export default withrouter(yourcomponent);
// app.tsx

import './app.css';

import react from 'react';
import { route, switch, router } from 'react-router-dom';

import yourcomponent from './yourcomponent';

function app(): jsx.element {
    return (
        <router>
            <switch>
                <route
                    path="/details/:id"
                    component={() => <yourcomponent />}
                />
            </switch>
        </router>
    );
}

export default app;

score:2

if you are using class component, you are most likely to use gserjo suggestion. pass in the params via <route> props to your target component:

exact path="/problem/:problemid" render={props => <problempage {...props.match.params} />}

score:3

this is for react-router-dom v6 (i highly suggest using functional components for this)

it's somewhat painful for react-router-dom to keep changing syntax and rules. but here goes nothing.

you can use both useparams and useselector to solve this

import { useparams } from 'react-router';
import { useselector } from 'react-redux';

const component = () => {
const { id } = useparams();                              //returns the :id
const page = useselector((state) => state.something[id]); //returns state of the page

return <div>page detail</div>;
}

export default component;

but, the problem persist when you also have an action creator and you want to pass it as a props in connect function

export const connect(mapstatetoprops, mapdispatchtoprops)(component)

since we are using useparams, it won't be passed to mapstatetoprops that we created

const mapstatetoprops = (state, ownprops) => {
console.log(ownprops)   //wont recognize :id
//hence
return {
  somereducers: state.somereducers[id] //would return an error: 'id' is not defined
 };
};

on the other hand, you can't entirely ignore the connect function since you need mapdispatchtoprops to work with your component.

the workaround to this is to create a higher order component withrouter function yourself. this was a deprecated react-router-dom helper.

//make this
import { useparams, uselocation, usenavigate } from 'react-router';
import { connect } from 'react-redux';
import { youractioncreator } from '../actioncreator';

const withrouter = (child) => {
return (props) => {
 const location = uselocation();
 const navigation = usenavigate();
 const params = useparams();
 return (
   <child
   {...props}
   params={params}
   navigate={navigate}
   location={location}
   />
  );
 };
};

const component = () => {
// your component...
return <div> page detail </div>
};

export mapstatetoprops = (state, ownprops) => {
console.log(ownprops)     // would contain the :id params
return {
//something
 }
};

const mapdispatchtoprops = {
youractioncreator
}

export withrouter(connect(mapstatetoprops, mapdispatchtoprops)(component));

score:4

another solution is to use a state and lifecycle hooks in the routed component and a search statement in the to property of the <link /> component. the search parameters can later be accessed via new urlsearchparams();

<link 
  key={id} 
  to={{
    pathname: this.props.match.url + '/' + foo,
    search: '?foo=' + foo
  }} />

<route path="/details/:foo" component={detailspage}/>

export default class detailspage extends component {

    state = {
        foo: ''
    }

    componentdidmount () {
        this.parsequeryparams();
    }

    componentdidupdate() {
        this.parsequeryparams();
    }

    parsequeryparams () {
        const query = new urlsearchparams(this.props.location.search);
        for (let param of query.entries()) {
            if (this.state.foo!== param[1]) {
                this.setstate({foo: param[1]});
            }
        }
    }

      render() {
        return(
          <div>
            <h2>{this.state.foo}</h2>
          </div>
        )
      }
    }

score:5

here's typescript version. works on "react-router-dom": "^4.3.1"

export const approuter: react.statelesscomponent = () => {
    return (
        <browserrouter>
            <switch>
                <route exact path="/problem/:problemid" render={props => <problempage {...props.match.params} />} />
                <route path="/" exact component={app} />
            </switch>
        </browserrouter>
    );
};

and component

export class problempage extends react.component<problemroutetokens> {

    public render(): jsx.element {
        return <div>{this.props.problemid}</div>;
    }
}

where problemroutetokens

export interface problemroutetokens { problemid: string; }

score:12

use the component:

<route exact path="/details/:id" component={detailspage} />

and you should be able to access the id using:

this.props.match.params.id

inside the detailspage component

score:14

in addition to alexander lunas answer ... if you want to add more than one argument just use:

<route path="/details/:id/:title" component={detailspage}/>

export default class detailspage extends component {
  render() {
    return(
      <div>
        <h2>{this.props.match.params.id}</h2>
        <h3>{this.props.match.params.title}</h3>
      </div>
    )
  }
}

score:40

use render method:

<route exact path="/details/:id" render={(props) => (
    <detailspage id={props.match.params.id}/>
)} />

and you should be able to access the id using:

this.props.id

inside the detailspage component

score:60

since react-router v5.1 with hooks:

import { useparams } from 'react-router';

export default function detailspage() {
  const { id } = useparams();
}

see https://reacttraining.com/blog/react-router-v5-1/

score:134

i used this to access the id in my component:

<route path="/details/:id" component={detailspage}/>

and in the detail component:

export default class detailspage extends component {
  render() {
    return(
      <div>
        <h2>{this.props.match.params.id}</h2>
      </div>
    )
  }
}

this will render any id inside an h2, hope that helps someone.


Related Query

More Query from same tag