I am a beginner in react js and I was implementing firebase authentication in my react app for sign up, login and redirect to homepage with react router. But when I enter the username, email id and password of a new user and click “sign up”, it’s taking me to the homepage and displaying “Login Please” on the first render. Only when I refresh the page again I am able to get “Welcome, ‘user_name’ “.
Intitial render of the homepage after sign up
app.js
import './App.css';
import Views from './Routes/Views';
import {BrowserRouter} from 'react-router-dom'
function App() {
return (
<BrowserRouter>
<Views />
</BrowserRouter>
);
}
export default App;
views.jsx
import { React, useEffect, useState } from "react";
import { Routes, Route } from "react-router-dom";
import { LoginSignup } from "../Components/LoginSignup/LoginSignup";
import { HomePage } from "../Components/HomePage/HomePage";
import { auth } from "../config/firebase";
const Views = () => {
const [userName, setUserName] = useState("");
useEffect(() => {
auth.onAuthStateChanged((accountUser) => {
if (accountUser) {
setUserName(accountUser.displayName);
} else {
setUserName("");
}
console.log(accountUser.displayName);
});
});
return (
<Routes>
<Route path="https://stackoverflow.com/" element={<LoginSignup />} />
<Route path="/home" element={<HomePage name={userName} />} />
<Route path="*" element={<div>404 Not Found!</div>} />
</Routes>
);
};
export default Views;
LoginSignup.jsx
import React, { useState, useRef, useEffect } from "react";
import "./LoginSignup.css";
import {
faCheck,
faTimes,
faInfoCircle,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { auth } from "../../config/firebase";
import { createUserWithEmailAndPassword, updateProfile } from "firebase/auth";
import { useNavigate } from "react-router-dom";
import user_icon from "../Assets/person.png";
import email_icon from "../Assets/email.png";
import password_icon from "../Assets/password.png";
const USER_REGEX = /^[A-z][A-z0-9-_]{3,23}$/;
const PWD_REGEX = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%]).{8,24}$/;
const EMAIL_REGEX = /^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/;
export const LoginSignup = () => {
const navigate = useNavigate();
const userRef = useRef();
const errRef = useRef();
const [action, setAction] = useState("Sign Up");
const [user, setUser] = useState("");
const [validName, setValidName] = useState(false);
const [userFocus, setUserFocus] = useState(false);
const [email, setEmail] = useState("");
const [validEmail, setValidEmail] = useState(false);
const [emailFocus, setEmailFocus] = useState(false);
const [password, setPassword] = useState("");
const [validPassword, setValidPassword] = useState(false);
const [passwordFocus, setPasswordFocus] = useState(false);
const [errMsg, setErrMsg] = useState("");
const [success, setSuccess] = useState(false);
useEffect(() => {
userRef.current.focus();
}, []);
useEffect(() => {
setValidName(USER_REGEX.test(user));
}, [user]);
useEffect(() => {
setValidPassword(PWD_REGEX.test(password));
}, [password]);
useEffect(() => {
setValidEmail(EMAIL_REGEX.test(email));
}, [email]);
useEffect(() => {
setErrMsg("");
}, [user, password, email]);
const handleSubmit = async (e) => {
e.preventDefault();
const v1 = USER_REGEX.test(user);
const v2 = PWD_REGEX.test(password);
const v3 = EMAIL_REGEX.test(email);
if (!v1 || !v2 || !v3) {
setErrMsg("Invalid Entry");
return;
}
createUserWithEmailAndPassword(auth, email, password)
.then(async (res) => {
const accountUser = res.user;
await updateProfile(accountUser, {
displayName: user,
});
navigate("/home");
})
.catch((err) => {
setErrMsg(err.message);
});
};
return (
<div className="loginPage">
<div className="titleAnimated">
<span className="text first-text">Welcome To </span>
<span className="text second-text">IntelliGuide</span>
</div>
<div className="container">
<p ref={errRef} className={errMsg ? "errMsg" : "offscreen"}></p>
<div className="header">
<div className="text">{action}</div>
<div className="underline"> </div>
</div>
<form onSubmit={handleSubmit}>
<div className="inputs">
{action === "Login" ? (
<div></div>
) : (
<>
<div className="labelStyle">
<label htmlFor="username">
Username:
<FontAwesomeIcon
icon={faCheck}
className={validName ? "valid" : "hide"}
/>
<FontAwesomeIcon
icon={faTimes}
className={validName || !user ? "hide" : "invalid"}
/>
</label>
</div>
<div className="input">
<img src={user_icon} alt="" />
<input
type="text"
id='username'
ref={userRef}
autoComplete="off"
onChange={(e) => setUser(e.target.value)}
required
aria-invalid={validName ? "false" : "true"}
aria-describedby='uidnote'
onFocus={() => setUserFocus(true)}
onBlur={() => setUserFocus(true)}
/>
</div>
<p
id='uidnote'
className={
userFocus && user && !validName
? "instructions"
: "offscreen"
}
>
<FontAwesomeIcon icon={faInfoCircle} />
4 to 24 characters.
<br />
Must begin with a letter.
<br />
Letters, numbers, underscores, hyphens allowed.
</p>
</>
)}
<>
<div className="labelStyle">
<label htmlFor="email">
Email Id:
<span className={validEmail ? "valid" : "hide"}>
<FontAwesomeIcon icon={faCheck} />
</span>
<span className={validEmail || !email ? "hide" : "invalid"}>
<FontAwesomeIcon icon={faTimes} />
</span>
</label>
</div>
<div className="input">
<img src={email_icon} alt="" />
<input
type="email"
id='email'
autoComplete="off"
value={email}
onChange={(e) => setEmail(e.target.value)}
aria-invalid={validEmail ? "false" : "true"}
aria-describedby='emailnote'
onFocus={() => setEmailFocus(true)}
onBlur={() => setEmailFocus(false)}
required
/>
</div>
</>
<>
<div className="labelStyle">
<label htmlFor="password">
Password:
<span className={validPassword ? "valid" : "hide"}>
<FontAwesomeIcon icon={faCheck} />
</span>
<span
className={validPassword || !password ? "hide" : "invalid"}
>
<FontAwesomeIcon icon={faTimes} />
</span>
</label>
</div>
<div className="input">
<img src={password_icon} alt="" />
<input
type="password"
id='password'
value={password}
onChange={(e) => setPassword(e.target.value)}
aria-invalid={validPassword ? "false" : "true"}
aria-describedby='pwdnote'
onFocus={() => setPasswordFocus(true)}
onBlur={() => setPasswordFocus(false)}
required
/>
</div>
<p
id='pwdnote'
className={
passwordFocus && !validPassword ? "instructions" : "offscreen"
}
>
<FontAwesomeIcon icon={faInfoCircle} />
8 to 24 characters.
<br />
Must include uppercase and lowercase letters, a number and a
special character.
<br />
Allowed special characters:{" "}
<span aria-label="exclamation mark">!</span>{" "}
<span aria-label="at symbol">@</span>{" "}
<span aria-label="hashtag">#</span>{" "}
<span aria-label="dollar sign">$</span>{" "}
<span aria-label="percent">%</span>
</p>
</>
{action === "Sign Up" ? (
<div className="hiddenClass"></div>
) : (
<div className="forgot-password">
Lost Password? <span>Click Here!</span>
</div>
)}
<div className="submit-container">
<button
className="submit"
disabled={
!validName || !validPassword || !validEmail ? true : false
}
onClick={() => {
setAction("Sign Up");
}}
>
Sign Up
</button>
<button
className="submit"
onClick={() => {
setAction("Login");
}}
>
Login
</button>
</div>
</div>
</form>
</div>
</div>
);
};
"HomePage.jsx"
import React from "react";
import "./HomePage.css";
export const HomePage = (props) => {
return (
<div className="containerHome">
<h1>HomePage</h1>
<h2>{props.name ? `Welcome, ${props.name}` : "Login Please"}</h2>
</div>
);
};
Since I am really new to firebase authentication I don’t know what to change in the views.jsx file. I was following a youtube video to learn these concepts. I was expecting the name of the user who creates the account to be displayed on the homepage without refreshing the homepage. But as things stand “Welcome, ‘user_name'” is only displayed if I refresh the page.