React this.props.params undefined
Asked Answered
K

10

30

I have problem passing id to my page with product, I tried everything and search answer but it still doesn't work.

Here is my index.js:

import React from "react";
import {render} from "react-dom";
import {Router, Route, IndexRoute, hashHistory} from "react-router";

import {Menu} from './components/Menu';
import {MainPage} from './components/MainPage';
import {DetailsProduct} from './components/DetailsProduct';

class App extends React.Component{

    render(){
        return(
        <Router history={hashHistory}>
            {/* <IndexRoute component={Menu}></IndexRoute> */}
            <Route path="/" component={()=>(<div><Menu/><MainPage/></div>)}></Route>
            <Route path={"product/:id"} component={()=>(<div><Menu/><DetailsProduct>asd</DetailsProduct></div>)}></Route>
        </Router>
        )
    }
}

render(<App/>, window.document.getElementById("app"));

And DetailsProduct (page: http://localhost:8080/#/product/1)

import React from "react";    
export class DetailsProduct extends React.Component{

    render(){
        console.log(this.props.params); <-- this is undefined

        return(
            <h1>Product</h1>
        )
    }
}

I came back here after a 3 years. Solution:

Rendering components in this way is not a good solution:

<Route path={"product/:id"} component={()=>(<div><Menu/><DetailsProduct>asd</DetailsProduct></div>)}></Route>

But if you want to render a component like this (which I do not recommend) you have to add props as param argument to the function and then make restructuring on the component in which you want that props({...props})

<Route path={"product/:id"} component={(props)=>(<div><Menu/><DetailsProduct>asd</DetailsProduct></div>)}></Route>

Best solution is render route like this:

<Route path={"product/:id"} component={DetailsProduct}></Route>

and inside DetailsProduct you can render <Menu /> or use Switch :

<Menu/>
<Switch>
    <Route exact path={"product/:id"} component={DetailsProduct}/>
    // Add any other routes you want here
</Switch>
Kranz answered 17/7, 2017 at 12:15 Comment(4)
What are you expect to see in this.props.params?Pd
I didn't see you are passing props to <DetailsProduct> ?Alden
<Route path={"product/:id"} component={DetailsProduct}></Route> it work now but i have to pass two components "Menu and DetailsProduct", Do u know how i can do this ?Johnnyjohnnycake
How about import the <Menu /> component in <DetailsProduct> ?Alden
K
0

I use

import { Router, Route, browserHistory, IndexRoute} from 'react-router'

and

import {syncHistoryWithStore, routerReducer} from 'react-router-redux'

then I can get id by this.props.params.id

Kranz answered 12/6, 2018 at 11:48 Comment(0)
N
25

I was also getting the same problem when I used this.props.params.id.

But when i tried to put console.log(this.props) in the component where I'm passing the id, it shows my id in match object so use:

this.props.match.params.id

to get the id (notice the added match).

Nicobarese answered 12/8, 2017 at 13:38 Comment(1)
Bump to why ^ works? is this based on react router version ?Spitter
V
24

For me I was using the render method and finding that this.props.match was undefined in rendered components. This was the solution for me, you have to pass in props.

this.props.match will be undefined for:

<Route path='/users/:id' render={() => <UserDetail/>}/>

Do this instead:

<Route path='/users/:id' render={(props) => <UserDetail {...props}/>}/>

https://reacttraining.com/react-router/web/api/Route/render-func

Vermouth answered 28/3, 2019 at 23:18 Comment(2)
props here can be a json object? I want to send props as well along with the match for id.Wringer
Thanks. Well spotted!Selfgovernment
B
14

replace this :

<Route path={"product/:id"} component={()=>(<div><Menu/><DetailsProduct>asd</DetailsProduct></div>)}></Route>

with :

<Route path={"product/:id"} component={DetailsProduct}></Route>
Bartram answered 17/7, 2017 at 12:29 Comment(4)
Wow Thanks it work, but how i can pass two components?Johnnyjohnnycake
Why do you want to pass 2 components to one route ? that wouldn't be right! Or if you are looking for nested routes/components that is quite possible.Bartram
@Bartram check my answer if you wanna still have multiple components in the routeFragmental
how do i convert path which i am passing props as well render={() => ( <HomeContent activeUser={this.props.activeUser} isGuest={this.state.isGuest} isSupp={this.state.isSupp} isReady={this.state.isReady} /> )}Pareto
S
4

in react-router-dom v6 you have to use useParams().

like this:

import { useParams } from 'react-router-dom';

const { id } = useParams();

this way you can access the id

Sumatra answered 21/12, 2022 at 12:52 Comment(0)
G
3

react router new version changed the route props object as the following: this.props.match.params instead this.props.params

https://reacttraining.com/react-router/web/api/match

Garnettgarnette answered 12/6, 2018 at 11:4 Comment(0)
R
3

In the new version you have to use

useParams()

instead

this.props.params
Retinol answered 17/3, 2022 at 18:15 Comment(0)
F
0

I assume you are not using react-router v4 but either v2.x.x or v3.x.x. In that case you should restructure your routes and you can pass multiple component using the components props as

   <Router history={hashHistory}>
        <Route path="/" component={Layout}>
              <IndexRoute components={{menu: Menu, mainPage: MainPage}}/>
              <Route path={"product/:id"} component={{menu: Menu, detail: DetailsProduct}}/>
         </Route>
    </Router>

And in the Menu Component Also the way you want it work is relatively very easy to do using react-router v4. In that case you can make use of prop render to provide a component and you could do the following with it

import {HashRouter as Router, Route} from 'react-router-dom';
...
<Router>
    <Route path="/" render={()=>(<div><Menu/><MainPage/></div>)}></Route>
    <Route path={"product/:id"} render={()=>(<div><Menu/><DetailsProduct>asd</DetailsProduct></div>)}></Route>
</Router>
Fragmental answered 17/7, 2017 at 14:46 Comment(0)
K
0

I use

import { Router, Route, browserHistory, IndexRoute} from 'react-router'

and

import {syncHistoryWithStore, routerReducer} from 'react-router-redux'

then I can get id by this.props.params.id

Kranz answered 12/6, 2018 at 11:48 Comment(0)
C
0

I had the same issue when I had this code

<Route
    path={"/:url"}
    render={(routerProps) =>
        <BusinessApps
            {...routerProps}
            {...this.props}
            size={size}
        />
    }/>

I removed {...this.props} to fix the issue.

Coze answered 15/7, 2021 at 19:12 Comment(0)
E
0

In React 6, you need to useParams like the following code when you pass it as a class-base:

import { useParams } from 'react-router-dom';

and for export write this:

export default (props) => (
<App
    {...props}
    params={useParams()}
/>

)

Finally you can use the params:

console.log(this.props.params);
Elysia answered 17/8, 2023 at 8:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.