I am building a simple to do app, and I have implemented a simple conditional rendering scheme, where I log "Hello world" if user is not authenticated, and I show the page if it is authenticated. However, even when the user is logged in, the "Hello world" is still logged to the console.
Here is my code
import React, { useState, useEffect } from "react";
import Tasks from "../tasks";
import { IoIosArrowBack } from "react-icons/io";
import { Link } from "react-router-dom";
import { auth } from "../../firebase";
import { onAuthStateChanged} from "firebase/auth";
const History = ({ tasks }) => {
const [authUser, setAuthUser] = useState(null);
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (user) => {
setAuthUser(user);
});
return () => {
unsubscribe();
};
}, []);
return (
<div>
{authUser ? (<React.Fragment>
<div className="navbar">
<Link to="/home" className="navbar-left">
<IoIosArrowBack style={{ fontSize: "35px" }} />
</Link>
<div className="navbar-right">
<div className="navbar-subtext">Finished tasks</div>
<div className="navbar-ut">
{tasks.filter((t) => t.completed === true).length}
</div>
</div>
</div>
<br />
<hr />
<Tasks
tasks={tasks}
remainingTasks={tasks.filter((t) => t.completed === true).length}
showCompleted={true}
/>
</React.Fragment>) : (console.log("Hello World"))}
</div>
);
};
export default History;
2
Answers
You should add a simple log statement in your component to find out how many times it renders, and the value of
authUser
at each rendering. It’s almost certainly the case that your component is rendering more than once:authUser
, which will benull
when the page first loadsauthUser
which will be an object describing the signed-in user (assuming a user was actually previously signed in).Firebase Auth state observers never trigger with signed-in user data when the page initially loads. They always trigger some time later after the user is known for sure to be signed in and their ID token is valid. Your component needs to be aware of this and render appropriately. Maybe use some sort of loading indicator to show that all of the information required to render the component is not yet available.
Read:
My personal opinion: using console.log in the middle of JSX is not a good way to debug the way a component works. Put your logging before the JSX to understand what is about to be rendered each time.
To fix this, you can move the console.log statement outside of the JSX and conditionally render it based on the authUser state. Here’s the updated code:
I’ve added a check to see if authUser is null. If it is null, the component returns null, which effectively renders nothing. This prevents the "Hello World" message from being logged when the user is not authenticated. If authUser is not null, the component continues to render the rest of its content as before.