1

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;

package.jsonpackage.json

7
  • Have you wrap your application with BrouserRouter ? Commented Aug 16, 2021 at 18:34
  • @MajidM. yes i have added additional code check it out Commented Aug 16, 2021 at 18:35
  • useHistory should be used in a children Component of Router. You're using it at root, so history is not defined Commented Aug 16, 2021 at 18:48
  • @dbuchet i shoud pass histroy as props then?? Commented Aug 16, 2021 at 18:52
  • 1
    Nope, you should only use useHistory within a children. So maybe just rewrite your component to have <Router> <App /></Router> and you'll be able to use useHistory in App Commented Aug 16, 2021 at 18:53

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

M , AoA bro thanks , still its not working , i have done the same previously this time i dont know why its not working its a simple thing .
@nodeDev Check my answer again.
thanks alot brother , really appreciate your help , i am going to implement your changes right now , thanks again :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.