'React Router V6 Class props empty [duplicate]
So I'm new to React and JS in general and have been following a course online. The thing is that, after a few chapters, I noticed that some stuff routes-related that the guy does do not work anymore. For example:
<Route path='/something' component={Something}/>
I spent the whole morning searching online. It seems that he uses a different version of react-router-dom than me. So I looked up how to do that same thing in newer versions from their official docs and eventually solved it by implementing routes like:
<Route path='/something' element={<Something/>} />
Now I have another problem. I want to fetch a parameter from the URL but it does not work either and the official docs only offer an example using functions (but I kinda need to use classes).
This is how I currently implement it:
<Route path='/profile/:user' element={<UserInfo/>}/>
UserInfo.js:
import React from 'react';
class UserInfo extends React.Component {
state = { user: '' }
componentDidMount() {
console.log(this)
let user = this.props.match.params.user;
this.setState({user:user});
}
render() {
const { user } = this.state
return(
<div>
<h1>{user}</h1>
</div>
)
}
}
export default Card
But it does not work either because this.props is empty "props: Object { }". There should be a match object but there is nothing inside (according to the dev console). How can I solve this without making UserInfo a function? Because I want to have states.
Solution 1:[1]
With react-router-dom V6 you can e.g. create a very simple HOC(higher order component) to be able to use useParams inside a class component.
HOC.js
import {useParams} from 'react-router-dom'
export function withParams(Component) {
return props => <Component {...props} params={useParams()} />;
}
Then include it in UserInfo.js
import React from "react";
import { withParams } from "./HOC";
class UserInfo extends React.Component {
constructor(props) {
super(props);
this.state = { user: "" };
}
componentDidMount() {
let user = this.props.params.user;
console.log(user);
this.setState({ user: user });
}
render() {
return (
<div>
<h1>{this.state.user}</h1>
</div>
);
}
}
export default withParams(UserInfo);
index.js
import ReactDOM from "react-dom";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import UserInfo from "./UserInfo";
const rootElement = document.getElementById("root");
ReactDOM.render(
<BrowserRouter>
<Routes>
<Route path={"/profile/:user"} element={<UserInfo />} />
</Routes>
</BrowserRouter>,
rootElement
);
Here is a Sandbox in case you need it:
The old react-router-dom V5 solution would be:
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Route } from "react-router-dom";
import UserInfo from "./UserInfo";
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<BrowserRouter>
<Route path={["/profile/:user"]} component={UserInfo} />
</BrowserRouter>
</StrictMode>,
rootElement
);
And access the user data inside the class component like that:
import React from "react";
class UserInfo extends React.Component {
constructor(props) {
super(props);
this.state = { user: "" };
}
componentDidMount() {
let user = this.props.match.params.user;
console.log(user);
this.setState({ user: user });
}
render() {
const { user } = this.state;
return (
<div>
<h1>{user}</h1>
</div>
);
}
}
export default UserInfo;
Solution 2:[2]
Try to add:
constructor(props) {
this.state = { user: '' };
}
instead of :
state = { user: '' }
I didn't run your code but I saw that immediately. And consider using functional components with hooks instead, that newer way and it standardizes react code.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Aleksandar Jockovic |
