8

I am trying to use my url as a parameter by passing the Match object into my react component class. However it is not working! What am I doing wrong here?

When I create my component as a JavaScript function it all works fine, but when I try to create my component as a JavaScript class it doesn't work.

Perhaps I am doing something wrong? How do I pass the Match object in to my class component and then use that to set my component's state?

My code:

import React, { Component } from 'react';

import axios from 'axios';

import PropTypes from 'prop-types';

class InstructorProfile extends Component {  

  constructor(props, {match}) {

    super(props, {match});

    this.state = {
        instructors: [],
        instructorID : match.params.instructorID
    };

  }

   componentDidMount(){


      axios.get(`/instructors`)
      .then(response => {
        this.setState({
          instructors: response.data
        });
      })
      .catch(error => {
        console.log('Error fetching and parsing data', error);
      });
    }

  render(){
    return (
      <div className="instructor-grid">

        <div className="instructor-wrapper">

       hi

        </div>

      </div>
    );
  }
}

export default InstructorProfile;
Michael Armes
  • 1,056
  • 2
  • 17
  • 31
vanegeek
  • 713
  • 2
  • 10
  • 22

5 Answers5

15

React-Router's Route component passes the match object to the component it wraps by default, via props. Try replacing your constructor method with the following:

constructor(props) {
    super(props);
    this.state = {
        instructors: [],
        instructorID : props.match.params.instructorID
    };
}

Hope this helps.

Veljo Lasn
  • 246
  • 1
  • 4
2

Your constructor only receives the props object, you have to put match in it...

constructor(props) {
  super(props);
  let match = props.match;//← here

  this.state = {
    instructors: [],
    instructorID : match.params.instructorID
  };
}

you then have to pass that match object via props int a parent component :

// in parent component...
render(){
  let match = ...;//however you get your match object upper in the hierarchy
  return <InstructorProfile match={match} /*and any other thing you need to pass it*/ />;
}
Boris
  • 1,161
  • 9
  • 20
  • Is it appropriate to capture the params in the constructor - is it guaranteed that the `match` object will be there when the component is constructed? – JoeTidee Oct 16 '18 at 13:26
  • Not guaranteed at all, but the question states that they are indeed passing the match to the component from start. I didn't want to complicate the answer. – Boris Nov 30 '18 at 08:49
1

for me this was not wrapping the component:

export default (withRouter(InstructorProfile))

you need to import withRouter:

import { withRouter } from 'react-router';

and then you can access match params via props:

  someFunc = () => {
      const { match, someOtherFunc } = this.props;
      const { params } = match;
      someOtherFunc(params.paramName1, params.paramName2);
  };
user326608
  • 2,210
  • 1
  • 26
  • 33
0

Using match inside a component class

As stated in the react router documentation. Use this.props.match in a component class. Use ({match}) in a regular function.

Use Case:

import React, {Component} from 'react';
import {Link, Route} from 'react-router-dom';
import DogsComponent from "./DogsComponent";

export default class Pets extends Component{
  render(){
    return (
      <div>
        <Link to={this.props.match.url+"/dogs"}>Dogs</Link>
        <Route path={this.props.match.path+"/dogs"} component={DogsComponent} />
      </div>
        
    )
      
  }
}

or using render

<Route path={this.props.match.path+"/dogs"} render={()=>{
  <p>You just clicked dog</p>
}} />

It just worked for me after days of research. Hope this helps.

Community
  • 1
  • 1
dondrzzy
  • 182
  • 1
  • 7
0

In a functional component match gets passed in as part of props like so:

export default function MyFunc(props) {
//some code for your component here...
}

In a class component it's already passed in; you just need to refer to it like this:

`export default class YourClass extends Component {
     render() {
        const {match} = this.props;
        console.log(match);
        ///other component code 
    }
}`
LydiaHendriks
  • 1,290
  • 2
  • 11
  • 19