Search code examples
react-routerreact-hooksbrowser-history

Error:TypeError: Cannot read property 'push' of undefined


I have made a login\Signup auth with firebase\react and i am trying to direct the user to the next page if the login or sign up are correct. But I keep getting the above error 'Error:TypeError: Cannot read property 'push' of undefined'. I am guessing there is an issue to where exactly and how to call history.push. can someone provide with a quick fix please? down below part of my code.

App.js

import React, { useEffect, useState } from "react";
import "./App.css";
import Contacts from "./components/Contacts";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import HomePage from "./components/HomePage";
import Login from "./components/Login";
import { useHistory } from "react-router-dom";
import { auth } from "./firebase";

    const App = () => {
      const history = useHistory();
      const [user, setUser] = useState("");
      const [email, setEmail] = useState("");
      const [password, setPassword] = useState("");
      const [emailError, setEmailError] = useState("");
      const [passwordError, setPasswordError] = useState("");
      const [hasAccount, setHasAccount] = useState(false);
    
      const clearInputs = () => {
        setEmail("");
        setPassword("");
      };
    
      const clearErrors = () => {
        setEmailError("");
        setPasswordError("");
      };
    
      const handleLogin = () =>{
        
        clearErrors();
        auth.signInWithEmailAndPassword(email, password)
        .then((u) => {
          console.log('successfully logged in')
          history.push('/HomePage')
          
        })
        .catch((err) => {
          console.log("Error:" + err.toString());
        });
      };
    
      const handleSignup = () => {
        clearErrors();
        auth
          .createUserWithEmailAndPassword(email, password)
          .then((u) => {
            console.log("successfully signed up");
            history.push('/HomePage')
            
          })
          .catch((err) => {
            console.log("Error:" + err.toString());
          });
      };
    
      const authListener = () => {
        auth.onAuthStateChanged((user) => {
          if (user) {
            clearInputs();
            setUser(user);
          } else {
            setUser("");
          }
        });
      };
    
      useEffect(() => {
        authListener();
      }, []);
    
      return (
        <Router>
          <div className="row">
            <div className="col-md-8 offset-md-2">
              <Switch>
                <Route exact path="/HomePage">
                  <HomePage />
                </Route>
                <Route exact path="/">
                  <Login
                    email={email}
                    setEmail={setEmail}
                    setPassword={setPassword}
                    password={password}
                    handleLogin={handleLogin}
                    handleSignup={handleSignup}
                    emailError={emailError}
                    passwordError={passwordError}
                    hasAccount={hasAccount}
                    setHasAccount={setHasAccount}
                  />
                </Route>
                <Route exact path="/Contacts">
                  <Contacts />
                </Route>
              </Switch>
            </div>
          </div>
        </Router>
      );
    };
    
    export default App;

Solution

  • The <Router> component should be one level above this component. otherwise you would not get access to history. useHistory only works inside a component that is already inside <Router>. Wherever you are using <App /> you can wrap it in .it should be like

    <Router><App /></Router>