Im trying to redirect my user when the user is logged in. but all my methods i found so far wont work. etg im trying to use useNavigate function using react router v6.
but for some reason i get the following error:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See react-invalid-hook-call for tips about how to debug and fix this problem.
at:
/login.jsx:35
let navigate = useNavigate();
function:
PerformLogin = () => {
let navigate = useNavigate();
const username = this.state.username;
const password = this.state.password;
if (username === '') {
console.log("please enter username");
} else if (password === '') {
console.log("please enter password");
} else {
console.log("username of login: ",this.state.username);
axios.post(process.env.REACT_APP_DATAURL + `/login`,{ username: username, password: password },{withCredentials: true})
.then(res => {
res = res.data;
console.log(res);
console.log(res.data);
if (res.type) {
console.log("navigating logged in");
navigate.push('/crime');
//return <Navigate to="/crime" />;
}
})
}
}
Q: what do i have to do to fix this and be able to redirect my user?
In react-router v6 there is no withRouter nor useHistory. I would recommend to refactor your component to use hooks for the sake of simplicity, but an alternative solution is to create a wrapper component that will pass the navigate function obtained from the hook as a prop:
import { useNavigate } from 'react-router-dom';
class MyComponent extends React.Component {
//...
PerformLogin = () => {
const username = this.state.username;
const password = this.state.password;
// ...
this.props.navigate('/crime');
}
}
function WithNavigate(props) {
let navigate = useNavigate();
return <MyComponent {...props} navigate={navigate} />
}
export default WithNavigate
useHistory is a hook and hooks can only be used inside "function" components.
However I can guess you are using it from a "class" component, since there are some this.state, so you cannot use the hook there.
Another approach that should work for you would be to wrap your component inside a withRouter:
import { withRouter } from "react-router";
class MyComponent extends React.Component {
//...
PerformLogin = () => {
const history = this.props.history;
const username = this.state.username;
const password = this.state.password;
// ...
}
}
export default withRouter(MyComponent)
The withRouter will inject the history as a prop.
In react-router-dom latest version(v6) you cannot use this.props.match.params.id and this.props.history (in react latest vesion history replace with navigate). Besides you cannot call them in class component. To call them in class component make a function first -
import { useParams, useNavigate } from "react-router-dom";
export function withParamsAndNavigate(Component) {
return (props) => (
<Component {...props} params={useParams()} navigate={useNavigate()} />
);
}
I want to use it for ProductDetails component. That's given below -
import { withParamsAndNavigate } from "./getParamsAndNavigate.js";
class ProductDetails extends React.Component {
state = {//}
render() {
const{params,navigate} = this.props;
// params.id - will return the id,
// navigate('yourUrl') - will redirect the target url.
return (
//
);
}
}
export default withParamsAndNavigate(ProductDetails);
Here is my App module where I defined my routes -
import React from "react";
import { Routes, Route} from "react-router-dom";
import Product from "./components/Product";
import ProductDetails "./components/ProductDetails";
function App() {
return (
<div>
<main role='main' className='container'>
<Routes>
<Route path='/product' element={<Product />} />
<Route path="/product/:id"} element={<ProductDetails />} />
</Routes>
</main>
</div>
);
}
export default App;
It works for me and hope it will help you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With