5

This is my URL in react js

http://localhost:3000/meassger/student/1

I want to extract 1 from the URL if it was a functional component I could have used ```useParams``

I am getting this error TypeError: Cannot read properties of undefined (reading 'params')

 componentDidMount() {
    console.log(this.props.match.params.id, "");
   
    };
5
  • Look at window.location object. Check path if includes student try some conditions Commented Apr 2, 2022 at 6:57
  • 1
    What router do you use? For react-router the way to access the params would be something like this props.match.params['paramName'] Commented Apr 2, 2022 at 7:00
  • @TeraWattHour can u write a answer based on my question it would be helpful for me and others Commented Apr 2, 2022 at 9:13
  • @meon did my solution work for you? Commented Apr 5, 2022 at 11:14
  • what version of react-router you are currently using? Commented Apr 6, 2022 at 0:18

4 Answers 4

3

You need to wrap it in withRouter - that injects the URL variables into your props.

You can find an example here: https://stackoverflow.com/a/60316195/13063136

The code:

import React from "react";
import { withRouter } from "react-router";

class ShowTheID extends React.Component {

  const { match } = this.props;

  componentDidMount() {
    console.log(match.params.id)
  }

  render() {
    return <div>{match.params.id}</div>;
  }
}

const ShowTheIDWithRouter = withRouter(ShowTheID);

Note: Along with wrapping your component in withRouter you also need to make sure that your route is registered and you have mentioned URL params in your Route path like path="/meassger/student/:id"

Sign up to request clarification or add additional context in comments.

Comments

3

Let's assume we have a url like http://localhost:3000/student/:studentId and we need to grab studentId param from this url

In a functional component, we can do it like

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

const Student = () => {
    const { studentId } = useParams();
    return (
        <div>StudentId: { studentId }</div>
    );
}
export default Student;

In a class based component, we can do it like

import React, { Component } from 'react';

class Student extends Component {
    render() {
        const { studentId } = this.props.match.params;
        return (
            <div>StudentId: { studentId }</div>
        );
    }
}
export default Student;

Alternatively, you can use withRouter HOC. By doing so, you can also access location and history props.

import React, { Component } from 'react';
import { withRouter } from "react-router";

class Student extends Component {
  render() {
    const { location, history } = this.props;

    return (
      <React.Fragment>
        <div>StudentId: { match.studentId }</div>
        <div>Path: {location.pathname}</div>
      </React.Fragment>
    );
  }
}

const StudentWithRouter = withRouter(Student);

Comments

3

In functional component, use

const history = useHistory()

const studentId = history?.location?.pathname.split('/')[3]

In class component, use

const studentId = window.location.href.split('/')[3]

5 Comments

There are specific methods in React for doing this kind of operation, e.g. withRouter. You should avoid doing direct manipulation of the window or document (where possible) because the React VDOM does not keep a track of that.
@crevulus The useHistory hook gives you access to the history instance that you may use to navigate. v5.reactrouter.com/web/api/Hooks
But this question is about class components and your method for class components is risky. Plus, you linked to react router v5 - in v5 useHistory is deprecated in favour of useNavigation.
@crevulus Please look here stackoverflow.com/questions/24078332/….
that answer is almost 8 years old... React didn't even exist then. In plain JS this method is fine - and it's not the worst thing in the world to do in React. But there is a React way to do things because React has the vdom which it needs to keep track of any and all changes/properties within the application. And using the correct methods, hooks etc. are safer when working in React because of this vdom. By directly interacting with window.location.href, you're circumventing the vdom. This should be avoided if at all possible.
0

Okay. I had the same issue and this is how I solved it. I created a separate component with the name getParams.jsx

getParams.jsx

import React from 'react'
import { useParams } from 'react-router-dom'
const getParams = AnyComponent =>props=> {
  return (
    <AnyComponent 
    {...props}
    params={params}>

    </AnyComponent>
  )
}

export default getParams

In now my component where i want to get the parameters, I gave it a different name. In this case, I will use the name of maybe your class based component assuming its name is Student.jsx

Student.jsx

import React, { Component } from 'react'
import getParams from './getParams'
class Student extends Component {
  constructor(props){
    super(props)
  }
  componentDidMount = () => {
//display the id when the component mounts
    console.log(this.props.params.id)
  }
  
  render = () => {
    return (
      <div>
        Student Id is :{this.props.params.id}
      </div>
    )
  }
}
export default getParams(Student)

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.