Search code examples
reactjsmern

× TypeError: Cannot read property 'push' of undefined in react.js


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


Solution

  • 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.