Reputation: 45
I'm new to Reactjs & Firebase, but I've managed to set up a signup/login system- now once the user logs in, I have them redirected back to the home page, but I want the nav bar to display 'profile' instead of the original 'log in'. I know this is something to do with Conditional Rendering but I'm having trouble implementing it with Firebase.
NavBar.js
import { Link } from 'react-router-dom'
// import { AuthProvider, useAuth } from '../contexts/AuthContext'
// import firebase from 'firebase/compat/app';
const NavBar = () => {
return (
<header>
<Link to = '/'>
<img src = {require('../images/logo.png')} alt = 'logo'/>
</Link>
<div id = 'nav-pages'>
<Link to='/contact'>contact</Link>
<Link to='/about'>about</Link>
{/* change this to a link to a profile page */}
<Link to='/login'>log-in</Link>
</div>
</header>
)
}
export default NavBar
LogIn.js
import React, { useRef, useState } from 'react'
import NavBar from '../components/NavBar'
import Footer from '../components/Footer'
import { Link, useNavigate } from 'react-router-dom';
import { AuthProvider, useAuth } from '../contexts/AuthContext'
// change to login css
import '../css/SignUp.css'
export default function Login(){
const emailRef = useRef();
const passwordRef = useRef();
const { login } = useAuth();
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const navigate = useNavigate();
async function handleSubmit(e){
e.preventDefault();
try {
setError("");
setLoading(true);
await login(emailRef.current.value, passwordRef.current.value);
navigate('/', {replace: true});
} catch {
setError('failed to sign in');
}
setLoading(false);
}
return (
<>
<NavBar/>
<div id = 'signup'>
<div id = 'card'>
<h2>log in</h2>
{error && <p id = 'error'>{error}</p>}
<form onSubmit={handleSubmit} id='form'>
<form id='email'>
<p>email</p>
<input type='email' ref = {emailRef} required/>
</form>
<form id='password'>
<p>password</p>
<input type='password' ref = {passwordRef} required/>
</form>
<button type='submit' disabled={loading}>log in</button>
</form>
</div>
<p>need an account? <Link to='/signup'>Sign Up</Link></p>
</div>
<Footer/>
</>
)
}
AuthContext.js
import React, { useContext, useState, useEffect } from 'react'
import { auth } from '../firebase';
const AuthContext = React.createContext()
export function useAuth(){
return useContext(AuthContext)
}
export function AuthProvider({ children }){
const [currentUser, setCurrentUser] = useState();
const [loading, setLoading] = useState(true);
function signup(email, password){
return auth.createUserWithEmailAndPassword(email, password)
}
function login(email, password){
return auth.signInWithEmailAndPassword(email,password)
}
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(user => {
setCurrentUser(user)
setLoading(false)
})
return unsubscribe
}, [])
const value = {
currentUser,
login,
signup,
}
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
);
}
Upvotes: 1
Views: 1994
Reputation: 478
I think you should be able to do this:
import { Link } from 'react-router-dom'
import { useAuth } from '../contexts/AuthContext'
// import firebase from 'firebase/compat/app';
const NavBar = () => {
let user = useAuth().currentUser;
return (
<header>
<Link to = '/'>
<img src = {require('../images/logo.png')} alt = 'logo'/>
</Link>
<div id = 'nav-pages'>
<Link to='/contact'>contact</Link>
<Link to='/about'>about</Link>
{user && <Link to="/profile" >Profile</Link>}
{!user && <Link to='/login'>log-in</Link>}
</div>
</header>
)
}
export default NavBar
So the line with useAuth().currentUser
will get the user from the context / provider.
And the line with { user && <xxx /> }
will be rendered when there is a user.
And the line with { !user && <xxx /> }
will be rendered when there is no user.
Upvotes: 1