I am trying to have my navbar update to show the user logged in info after they attempt to login and it is successful. Here's the relevant code files:
App.js
class App extends Component {
render(){
return (
<div>
<div className="App">
<header className="App-header">
<NavBar />
<Main />
</header>
</div>
</div>
);
}
}
export default App;
NavBar.js
const NavBar = () => {
const [userInfo, SetUserInfo] = useState();
useEffect(() => {
SetNavBar(null);
}, [])
function SetNavBar(element){
var user = auth.currentUser;
console.log(auth.currentUser);
if (user){
var userInfo =
React.createElement('div', {id : 'userDiv'},
React.createElement('span', {id : 'userDisplayName'}, user.email),
React.createElement('span', {id : 'signoutSpan'},
'(',
React.createElement('button', {id : 'signoutButton', onClick : (e) => SignOutUser(e.target)}, 'Signout'),
')'
)
);
SetUserInfo(userInfo);
}
else if(element != null && element.nodeName === 'A'){
var urlTO = element.href;
if(!urlTO.includes("login") && !urlTO.includes("signup")){
var userLoginSignupElement =
React.createElement('span', {id : 'loginSignupOptions'},
React.createElement(Link, {to : '/login', onClick : (e) => SetNavBar(e.target)}, 'Login'),
'/',
React.createElement(Link, {to : '/signup', onClick : (e) => SetNavBar(e.target)}, 'Signup')
);
}
else{
var userLoginSignupElement = null;
}
SetUserInfo(userLoginSignupElement);
}
else{
var userLoginSignupElement =
React.createElement('span', {id : 'loginSignupOptions'},
React.createElement(Link, {to : '/login', onClick : (e) => SetNavBar(e.target)}, 'Login'),
'/',
React.createElement(Link, {to : '/signup', onClick : (e) => SetNavBar(e.target)}, 'Signup')
);
SetUserInfo(userLoginSignupElement);
}
}
async function SignOutUser(element){
try{
await signOut(auth);
SetNavBar(null)
}
catch(err){
console.log(err);
}
}
return (
<div>
<nav id='navBar'>
<div id='logoTitleDiv'>
<img id='navBarLogo' src={logo} alt='Skeeters logo.'></img>
<Link to='/' onClick={e => SetNavBar(e.target)}>
<h2 id='pageHeader'>DJSkeeterB</h2>
</Link>
</div>
{userInfo}
</nav>
</div>
);
}
export default NavBar;
Main.js
const Main = () => {
return (
<div id='main'>
<Routes>
<Route exact path='/' element={<SongRequests/>}/>
<Route exact path='/upcoming' element={<Upcoming/>}/>
<Route exact path='/signup' element={<Signup/>}/>
<Route exact path='/login' element={<Login/>}/>
</Routes>
</div>
);
}
export default Main;
Login.js
const Login = () => {
const [navigateToHome, SetNavigateToHome] = useState(false);
const [userEmail, SetUserEmail] = useState('');
const [userPassword, SetUserPassword] = useState('');
const userEmailRef = useRef('');
userEmailRef.current = userEmail;
const userPasswordRef = useRef('');
userPasswordRef.current = userPassword;
const LoginToFirebase = async () => {
try {
await signInWithEmailAndPassword(auth, userEmailRef.current, userPasswordRef.current);
console.log(auth.currentUser);
document.getElementById('emailInput').innerHTML = '';
document.getElementById('passwordInput').innerHTML = '';
SetUserEmail('');
SetUserPassword('');
SetNavigateToHome(true);
} catch (err) {
console.error(err);
}
};
if(navigateToHome === true){
return <Navigate to='/'/>;
}
return (
<div id='loginDiv'>
<div>
<h2>Login</h2>
</div>
<div>
<label>Email: </label>
<input id='emailInput' type='email' placeholder='[email protected]' onChange={e => SetUserEmail(e.target.value)}/>
</div>
<div>
<label>Password: </label>
<input id='passwordInput' type='password' placeholder='Password' onChange={e => SetUserPassword(e.target.value)}/>
</div>
<button onClick={e => LoginToFirebase()}>Submit</button>
<div>
<span id='alreadySignedUpSpan'>
<Link to='/signup'>Not registered? Signup here</Link>
</span>
</div>
</div>
);
}
export default Login;
Essentially I have my app show the navbar at all times, and depending on page or user authenticated it updates to be different. The component Main
is using react-router-dom to link a few pages currently. After the user signs in or signs up on Login.js
or Signup.js
they are redirected to the main page. They are successfully logged in using firebase authentication. After the redirect they land on the main page but the navbar isn't updating as I don't know how to call for a state change from what's happening in Login.js
to affect NavBar.js
.
The navbar has no way of knowing this was a successful authentication it seems. I tried treating auth
and auth.currentUser
as states to see if when they update they could be used in a useEffect(() => {}, [auth])
way to call the SetNavBar function in NavBar.js
.
How can I update my component NavBar
, at the end of my function LoginToFirebase()
function?
CodePudding user response:
By lifting userEmail
state up to your App component (and perhaps all the login functionality) and making your Login
component accept a prop of onClickLogin
.