I am trying to use the useHistory hook in react.js , i dont't understand why i am getting error can not react property push of undefined .
code:
import { useHistory } from "react-router-dom";
function App() {
const [loader, setLoader] = useState(false);
const [errMsg, setErrMsg] = useState("");
const [signinLoader, setsinginLoader] = useState(false);
const [opterror, setoptError] = useState("");
const history = useHistory()
useEffect(() => {
const userInfo = localStorage.getItem("userInfo");
if (userInfo) {
history.push("/users");
}
}, [history]);
here is complete code of my app.js file check the useState hook where i am trying to use useHistory hook but its not working , getting error cannot read push of undefined
import "./App.css";
import axios from "axios";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Signup from "./components/Signup";
import Signin from "./components/login";
import Users from "./components/users";
import { useState, useEffect } from "react";
import { useHistory } from "react-router";
function App() {
const [loader, setLoader] = useState(false);
const [errMsg, setErrMsg] = useState("");
const [signinLoader, setsinginLoader] = useState(false);
const [opterror, setoptError] = useState("");
const history = useHistory()
useEffect(() => {
const userInfo = localStorage.getItem("userInfo");
if (userInfo) {
history.push("/");
}
}, [history]);
const formDataSender = async (FormData) => {
setLoader(true);
try {
if (FormData) {
let res = await axios.post("/api/users", FormData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
if (res) {
setLoader(false);
console.log(res);
setTimeout(() => {
setErrMsg("");
}, 1000);
return setErrMsg(res.data.message);
}
return setErrMsg(true);
}
} catch (error) {
setErrMsg(true);
}
};
const timer = (message) => {
setTimeout(() => {
setoptError(message);
}, 1000);
};
const loginSender = async (formData) => {
if (formData) {
setsinginLoader(true);
try {
let res = await axios.post("/api/users/login", formData);
console.log(res);
if (res.data.message) {
localStorage.setItem("userInfo", JSON.stringify(res.data));
setsinginLoader(false);
setoptError("login successful !");
timer("");
return console.log(res);
}
setsinginLoader(false);
setoptError(res.data.showmessage);
timer("");
} catch (error) {
timer("");
setoptError("login failed !!");
}
}
};
return (
<Router>
<Switch>
<div className="App">
<Route path="/" exact>
<Signin
passtologinhandler={loginSender}
loader={signinLoader}
additionalInfo={opterror}
/>
</Route>
<Route path="/signup">
<Signup
passedToSignUpHandler={formDataSender}
loading={loader}
err={errMsg}
/>
</Route>
<Route path="/users">
<Users />
</Route>
</div>
</Switch>
</Router>
);
}
export default App;
Instead of passing the loginSender
,signinLoader
,opterror
as props in Signin
component. Move all the functionality into Signin
component. So in the Signin
component, you should have something like this:
export const Signin =(props)=>{
const [signinLoader, setsinginLoader] = useState(false);
const [opterror, setoptError] = useState("");
useEffect(() => {
const userInfo = localStorage.getItem("userInfo");
if (userInfo) {
history.push("/");
}
}, []);
const loginSender = async (formData) => {
if (formData) {
setsinginLoader(true);
try {
let res = await axios.post("/api/users/login", formData);
console.log(res);
if (res.data.message) {
localStorage.setItem("userInfo", JSON.stringify(res.data));
setsinginLoader(false);
setoptError("login successful !");
timer("");
return console.log(res);
}
setsinginLoader(false);
setoptError(res.data.showmessage);
timer("");
} catch (error) {
timer("");
setoptError("login failed !!");
}
}
};
....
}
App:
return (
<BrowserRouter>
<Switch>
<div className="App">
<Route path="/" exact>
<Signin/>
</Route>
<Route path="/signup">
<Signup/>
</Route>
<Route path="/users">
<Users />
</Route>
</div>
</Switch>
</BrowserRouter>
);
}
You should do the same thing for Signup
.