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.
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;
There is no reason to have a class here, they kinda useless now that we have hooks.
To get a state in a functional component, you can use the hook useState. This way you reproduce what you know about state in a class, but in a function. Here is an example :
import React, { Component } from "react";
import { render } from "react-dom";
import "./style.css";
const App = () => {
const [myState, setMyState] = React.useState();
return (
<div>
My state = {myState}<br />
<button onClick={() => setMyState(Math.random())}> Edit my state</button>
</div>
);
};
render(<App />, document.getElementById("root"));
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.