alexsmt
alexsmt

Reputation: 71

useEffect unwanted side effect when refresh page

In my account page, after logging in, I want to display dynamic ways of greeting plus the name of the user from the firebase users document. I use react typed for the greetings.

When I login, everything seems to work well; but, when I refresh the page, all the content vanish and in console I get the following error message:

index.esm2017.js:1032 Uncaught TypeError: Cannot read properties of undefined (reading 'indexOf').

However, if I remove the user from dependencies array in useEffect, the error is gone but, in the console, I see how it loops infinitely. I think this is because of react typed.

Can someone, please, tell me what am I doing wrong and explain how to use useEffect properly in this situation?

Here is the code:

import React, { useState, useEffect } from "react";
import Typed from "react-typed";
import { UserAuth } from "../contexts/AuthContext";
import { db } from "../utils/firebase/firebase.utils";
import { doc, getDoc } from "firebase/firestore";

const Hero = () => {
  const [userDetails, setUserDetails] = useState({});
  const { user } = UserAuth();

  useEffect(() => {
    const docRef = doc(db, "users", user.uid);

    const fetchData = async () => {
      const docSnap = await getDoc(docRef);
      setUserDetails(docSnap.data());
      console.log(docSnap.data());
    };
    fetchData();
  }, [user]);

  return (
    <div className="text-white">
      <div className="max-w-[800px] mt-[-96px] w-full h-screen mx-auto text-center flex flex-col justify-center">
        <div className="flex justify-center items-center">
          <Typed
            className="md:text-5xl sm:text-4xl text-xl font-bold md:pl-4 pl-2"
            strings={["Hello,", "Hola,"]}
            typeSpeed={120}
            backSpeed={140}
            loop
          />
          <p className="md:text-5xl sm:text-4xl text-xl font-bold py-4">
            {userDetails.displayName}!
          </p>
        </div>
      </div>
    </div>
  );
};

export default Hero;

Upvotes: 0

Views: 703

Answers (1)

Hassan Ahmed
Hassan Ahmed

Reputation: 114

Likely the error is being caused because user or userDetails doesn't exist when your useEffect is run for the first time and user.uid is causing the error.

Can do something like this to solve the issue

useEffect(() => {
    if (!user) return;

    const docRef = doc(db, "users", user.uid);

    const fetchData = async () => {
      const docSnap = await getDoc(docRef);
      setUserDetails(docSnap.data());
      console.log(docSnap.data());
    };
    fetchData();
  }, [user]);

if (!user && userDetails === {}) {
  return <div>Loading.</div<
}

Though the UserAuth() hook might have a loading property that it returns that can be used instead for a better way of doing this.

Upvotes: 1

Related Questions