What I want is to show the Homepage only if user has previously logged in and didn't logged out. But is user logged out previously then show loginpage. I'm saving auth status to local storage like this: key:auth, value:true/false. Depending on auth value I want to render the starting page.
This is my App.js:
import "./App.css";
import "bootstrap/dist/css/bootstrap.min.css";
import Signup from "./Components/Signup";
import Login from "./Components/Login";
import { Routes, Route, Navigate } from "react-router-dom";
import HomePage from "./Components/HomePage";
import { useEffect, useState } from "react";
function App() {
const [isAuthenticated, setIsAuthenticated] = useState(false);
const authStatus=localStorage.getItem('auth')
const setAuth = (value) => {
setIsAuthenticated(value);
//alert(value);
};
useEffect(()=>{
setIsAuthenticated(authStatus)
},[])
return (
<>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<Signup />} />
</Routes>
</>
);
}
export default App;
Its always opening Homepage in the starting but I want Homepage if user login status is true which is saved on localStorage of the browser and Login page if login status is false.
This is my login.js:
import React, { useState } from "react";
import Form from "react-bootstrap/Form";
import Button from "react-bootstrap/Button";
import { Link, useNavigate } from "react-router-dom";
const initialValues = {
email: "",
password: "",
};
export default function Login({setAuth}) {
const navigate = useNavigate();
const [values, setValues] = useState(initialValues);
function validateForm() {
return values.email.length > 0 && values.password.length > 0;
}
const handleSubmit = (e) => {
e.preventDefault();
Login();
};
const handleInputChange = (e) => {
e.preventDefault();
const { name, value } = e.target;
setValues({
...values,
[name]: value,
});
};
function Login() {
let retrievedData = localStorage.getItem("registeredUsers");
let users = JSON.parse(retrievedData);
let Found = users.find(function (user, index) {
if (user.email === values.email && user.password === values.password) {
return true;
}
});
if (Found) {
setAuth(true)
let auth = true;
localStorage.setItem("auth", JSON.stringify(auth));
//navigate("/");
} else {
alert("Error email/password");
}
}
return (
<div className="LoginContainer">
<div style={{ display: "flex", width: "100%" }}>
<Form onSubmit={handleSubmit}>
<Form.Group size="lg" controlId="email">
<Form.Label>Email</Form.Label>
<Form.Control
autoFocus
type="email"
name="email"
value={values.email}
onChange={handleInputChange}
/>
</Form.Group>
<Form.Group size="lg" controlId="password">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
name="password"
value={values.password}
onChange={handleInputChange}
/>
</Form.Group>
<Button
style={{ marginTop: 10, width: 400 }}
block
size="lg"
type="submit"
// disabled={!validateForm()}
>
Login
</Button>
</Form>
</div>
<text style={{ marginTop: 10 }}>
Don't have an account? <Link to="/signup">Register</Link>
</text>
</div>
)
}
CodePudding user response:
It looks like your getting your auth
info from local storage but not actually using it anywhere. You should be able to do a conditional route based on if the user is authenticated or not. Something like this.
<Routes>
<Route path="/" element={ isAuthenticated ? <HomePage /> : <Login />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<Signup />} />
</Routes>
Or you could also use a redirect when you are running your setAuth
method. If the current path is /
and they dont have the auth
coookie then redirect them to /login
This answer explains a few different ways to achieve the redirect if you chose that way.
CodePudding user response:
Issues
- Your initial
isAuthenticated
state matches your unauthenticated state. - The render doesn't handle any conditional rendering of the homepage or redirecting to your login page.
- The
Login
component isn't passed thesetAuth
callback.
Solution
Initialize the isAuthenticated
from localStorage, use the useEffect
hook with dependency on isAuthenticated
to persist authentication state changes to localStorage.
function App() {
const [isAuthenticated, setIsAuthenticated] = useState(
() => JSON.parse(localStorage.getItem('auth')) || false
);
const setAuth = (value) => {
setIsAuthenticated(value);
//alert(value);
};
useEffect(()=>{
localStorage.setItem("auth", JSON.stringify(isAuthenticated));
}, [isAuthenticated]);
return (
<>
<Routes>
<Route
path="/"
element={isAuthenticated
? <HomePage />
: <Navigate to="/login" replace />
}
/>
<Route path="/login" element={<Login setAuth={setAuth} />} />
<Route path="/signup" element={<Signup />} />
</Routes>
</>
);
}
Login
Update the login function to only call the setAuth
callback and then imperatively navigate to the homepage.
const handleSubmit = (e) => {
e.preventDefault();
login();
};
...
function login() {
const users = JSON.parse(localStorage.getItem("registeredUsers")) || [];
const found = users.some(user => user.email === values.email && user.password === values.password);
if (found) {
setAuth(found);
navigate("/", { replace: true });
} else {
alert("Error email/password");
}
}