So I am using firebase authentication, and I was getting a hydration error , as I was not handling the "createUserWithEmailAndPassword" and "signInWithEmailAndPassword" async functions correctly, I was storing them inside of a variable , and also I did not have a loading state as well initially , but now in my new code I am not storing these async functions in a separate variable and also using loading state, below are my new codes and also the incorrect ones as well:
New Code:
"use client";
import {
createUserWithEmailAndPassword,
onAuthStateChanged,
} from "firebase/auth";
import { useEffect, useState } from "react";
import { auth } from "../lib/firebaseconfig";
import { useRouter } from "next/navigation";
export default function SingUp() {
const router = useRouter();
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [loading, setLoading] = useState(true);
const [user, setUser] = useState(null);
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
setUser(currentUser);
setLoading(false);
});
return () => unsubscribe();
}, []);
async function handleSignUp(e) {
e.preventDefault();
try {
await createUserWithEmailAndPassword(auth, email, password);
console.log("User signed up");
router.push("/login");
} catch (error) {
console.error("Error adding user to the system", error.message);
}
}
if (loading) return <p>Loading...</p>;
return (
<>
<form onSubmit={handleSignUp}>
<input
placeholder="Enter emailId"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
className="border-2"
/>
<br />
<br />
<input
placeholder="Enter password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="border-2"
/>
<br />
<br />
<button type="submit" className="border-4">
Sign-up
</button>
</form>
</>
);
}
Incorrect version of this code
"use client";
import {
createUserWithEmailAndPassword,
onAuthStateChanged,
} from "firebase/auth";
import { useEffect, useState } from "react";
import { auth } from "../lib/firebaseconfig";
import { useRouter } from "next/navigation";
export default function SingUp() {
const router = useRouter();
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [user, setUser] = useState(null);
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
setUser(currentUser);
setLoading(false);
});
return () => unsubscribe();
}, []);
async function handleSignUp(e) {
e.preventDefault();
try {
const userCredentials = await createUserWithEmailAndPassword(auth, email, password);
const user = userCredentials.user
console.log("User signed up");
router.push("/login");
} catch (error) {
console.error("Error adding user to the system", error.message);
}
}
return (
<>
<form onSubmit={handleSignUp}>
<input
placeholder="Enter emailId"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
className="border-2"
/>
<br />
<br />
<input
placeholder="Enter password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="border-2"
/>
<br />
<br />
<button type="submit" className="border-4">
Sign-up
</button>
</form>
</>
);
}
As you can see I was not using Loading state and also I was storing the "createUserWithEmailAndPassword" function inside of a variable.
Now I wanted to know - is storing any async function that gives us some final data give us some kind of hydration error , or in such cases where we are fetching some data and the state depends on that data , a loading state is required to wait for the data to be loaded and then use it , to avoid hydration errors.
PS: Apologies if this question is not structured properly, but would appreciate your insights on this, Thanks in advance.