1

The problem is when after i login and then i click in the store tab, it still redirects me to the login page always.

This is my App.js file, in here i am using auth context and isLogin value to determine if the user is logged in or not.

import { Redirect, Route, Switch } from "react-router-dom";
import CartProvider from "../src/Store/CartProvider";
import Footer from "./Footer";
import Headers from "./Headers";
import About from "./About/About";
import Store from "../src/Store/Store";
import Home from "./Home/Home";
import ContactUs from "./ContactUs/ContectUs";
import ProductDetails from "../src/Store/ProductDetails";
import Login from "./Login/Login";
import AuthProvider from "./Login/AuthProvider";
import { useContext } from "react";
import AuthContext from "./Login/auth-context";

function App() {
  const authCtx = useContext(AuthContext);
  console.log(authCtx)
  return (
    <div className="App">
      <AuthProvider>
        <CartProvider>
          <Headers />
          {/* <Switch> */}
            <Route path="/" exact>
              <Redirect to="/home" />
            </Route>
            <Route path="/home">
              <Home />
            </Route>
            {console.log(`rerendering app.js`)}
            <Route path="/store">
            {console.log(`rerendering app.js inside route store`)}
          {authCtx.isLogin && <Store />}
          {!authCtx.isLogin && <Redirect to='/auth' />}
          </Route>
            {/* <Route path="/store">
              <Store />
            </Route> */}
            <Route path="/auth">
              <Login />
            </Route>
            <Route path="/about">
              <About />
            </Route>
            <Route path="/contactUs">
              <ContactUs />
            </Route>
            <Route path="/product/:productId">
              <ProductDetails />
            </Route>
          {/* </Switch> */}
          <Footer />
        </CartProvider>
      </AuthProvider>
    </div>
  );
}

export default App;

This is my AuthProvider file contatins detail about how am i setting the value of isLogin

import { useState } from "react"
import AuthContext from "./auth-context"

const AuthProvider = (props) => {
    console.log(`hii`)
    const [token, setToken] = useState(null)
    const [isLogin, setIsLogin] = useState(false);

    // const isLogin = !!token;
    // let isLogin1 = false
    // console.log(isLogin)

    const loginHandler = (idToken) => {

        setToken(idToken)
        setIsLogin(true)
        console.log(`afer setToken`)
    }

    console.log(`afer loginHandler`)

    const authContext = {

        token: token,
        isLogin: isLogin, 
        login: loginHandler
    }
    console.log(authContext)
    return <AuthContext.Provider value={authContext}>
        {props.children}
    </AuthContext.Provider>
}

export default AuthProvider

This is my Auth Context file, simple Auth Context file

import { createContext } from "react";

const AuthContext = createContext({

    token: '',
    isLogin: false, 
    login: (idToken) => {}
});

export default AuthContext;

This is my header file, i am not sure but might you may want to have a look. In this file there is NavLink which you know changes the url

import { useContext } from "react";
import { NavLink } from "react-router-dom";

import classes from "./Headers.module.css";
import AuthContext from "./Login/auth-context";

const Heading = () => {
  console.log(`headers`)
  const authCtx = useContext(AuthContext)
    
  return (
    <>
      <ul className={classes.menu}>
        <li>
          <NavLink to="/home">Home</NavLink>
        </li>
        <li>
          <NavLink to="/store">Store</NavLink>
        </li>
        <li>
          <NavLink to="/about">About</NavLink>
        </li>
        <li>
          <NavLink to="/auth">Login</NavLink>
        </li>
        <li>
          <NavLink to="/contactUs">Contact US</NavLink>
        </li>
      </ul>
      <h1 className={classes.heading}>The Generics</h1>
    </>
  );
};

export default Heading;

This is my login.js file, details regarding when i click on login button and so

import axios from "axios";
import { useContext, useEffect, useRef } from "react";
import { Redirect, useHistory } from "react-router-dom";
import AuthContext from "./auth-context";

const Login = () => {
  const emailInputRef = useRef();
  const passwordInputRef = useRef();

  const history = useHistory();
  const authCtx = useContext(AuthContext);

  // useEffect(() => {

  //   console.log(authCtx.isLogin)
  //   if(authCtx.isLogin) {
  //     <Redirect to="/store" />
  //   }
  // }, [authCtx.isLogin])

  const onLoginSubmitHandler = async (event) => {
    event.preventDefault();

    const enteredEmail = emailInputRef.current.value;
    const enteredPassword = passwordInputRef.current.value;

    try {
      const response = await axios.post(
        "<Here is my POST request API using firebase as backend>",
        {
          email: enteredEmail,
          password: enteredPassword,
          returnSecureToken: true,
        }
      );

      const token = response.data.idToken;
      authCtx.login(token);
      console.log(authCtx.isLogin)
      history.replace('/store')
    } catch (error) {
      console.log(error);
    }

    console.log(`before redirect to store`);

    // <Redirect to='/store' />
    // history.replace('/store')
    console.log(`inside submit handler`);
  };

  return (
    <>
      <form onSubmit={onLoginSubmitHandler}>
        <div>
          <span>Email</span>
          <input type="text" ref={emailInputRef}></input>
        </div>
        <div>
          <span>Password</span>
          <input type="text" ref={passwordInputRef}></input>
        </div>
        <div>
          <button>Login</button>
        </div>
      </form>
    </>
  );
};

export default Login;

enter image description here

Manan
  • 49
  • 8

1 Answers1

0

Issue

From what I can see of the code you shared the issue is caused by the App component being the component providing the AuthContext value, so it can't use the AuthContext itself.

Solution

Promote the AuthProvider higher in the ReactTree than the App component so it can consume and use the AuthContext value it provides.

Example

<AuthProvider>
  </App />
</AuthProvider>

...

function App() {
  const authCtx = useContext(AuthContext);

  return (
    <div className="App">
      <CartProvider>
        <Headers />
        <Switch>
          <Route path="/product/:productId">
            <ProductDetails />
          </Route>
          <Route path="/home">
            <Home />
          </Route>
          <Route path="/store">
            {authCtx.isLogin && <Store />}
            {!authCtx.isLogin && <Redirect to='/auth' />}
          </Route>
          <Route path="/store">
            <Store />
          </Route>
          <Route path="/auth">
            <Login />
          </Route>
          <Route path="/about">
            <About />
          </Route>
          <Route path="/contactUs">
            <ContactUs />
          </Route>
          <Redirect from="/" exact to="/home" />
        </Switch>
        <Footer />
      </CartProvider>
    </div>
  );
}
Drew Reese
  • 165,259
  • 14
  • 153
  • 181