node Dev
node Dev

Reputation: 69

× 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

Upvotes: 1

Views: 463

Answers (1)

Majid M.
Majid M.

Reputation: 4964

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.

Upvotes: 1

Related Questions