reactjs

Getting this.props.match.params.id is undefined


I have the following React code. I'm trying to access this.props.match.params.id which used to work in previous versions of React, but it's undefined. Please see the fetch function below

import React, { Component } from "react";
import axios from "../../axios";
import Spinner from "../Spinner/Spinner";

class Event extends Component {
    state = {
        result: null,
        loading: true,
    };

    fetch() {
        console.dir(this.props.match);
        axios
            .get(`/api/events/${this.props.match.params.id}`)
            .then((response) => {
                this.setState({
                    user: response.data.result,
                    loading: false,
                });
            })
            .catch((error) => {
                console.dir(error);
                this.setState({ error: error });
            });
    }

    componentDidMount() {
        this.fetch();
    }

    render() {
        if (this.state.loading) {
            return <Spinner />;
        }
        const event = this.state.result;
        return <div className="Event">{event.title}</div>
    }
}

export default Event;

Here's my App.js

export default function App() {
    return (
        <BrowserRouter>
            <Routes>
                <Route path="/" element={<Layout />}>
                    <Route path="admin/add-event" element={<AddEvent />} />
                    <Route path="admin/events" element={<AdminEvents />} />
                    <Route path="events" element={<Events />} />
                    <Route path="events/:id" element={<Event />} />
                </Route>
            </Routes>
        </BrowserRouter>
    );
}

What can I try to resolve this?


Solution

  • So because newer versions are based around hooks in functional components, you need to add a HOC to your route to access the params:

    import { withRouter } from "react-router";
    
    
    class Event extends Component {
    
     ... your class component code
    
    }
    
    export default withRouter(Event);
    
    

    There is a change that may not work with certain versions of react router, in which case you need to create your own HOC:

    import { useNavigate, useParams } from "react-router-dom";
    
    export const withRouter = (WrappedComponent) => (props) => {
      const params = useParams();
      const navigate = useNavigate();
    
      return <WrappedComponent {...props} params={params} navigate={navigate} />;
    };