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> ); }
Advertisement
Answer
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.