firebase useEffect刷新页面时不需要副作用

2vuwiymt  于 2022-11-17  发布在  其他
关注(0)|答案(1)|浏览(148)

在我的帐户页面中,登录后,我想显示动态的问候方式,以及来自firebase用户文档的用户名。
当我登录时,一切似乎都运行良好;但是,当我刷新页面时,所有内容都消失了,并且在控制台中我收到以下错误消息:
系统提示:1032未捕获类型错误:无法读取undefined的属性(阅读'indexOf')。
然而,如果我从useEffect的依赖项数组中删除用户,错误就消失了,但是在控制台中,我看到它是如何无限循环的。我认为这是因为react类型。
请有人告诉我我做错了什么,并解释如何在这种情况下正确使用useEffect
代码如下:

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;
bnlyeluc

bnlyeluc1#

导致此错误的原因可能是首次运行useEffect时user或userDetails不存在,并且user.uid导致了此错误。
可以这样做来解决问题

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<
}

尽管UserAuth()钩子可能有一个它返回的loading属性,但可以使用该属性来更好地完成此操作。

相关问题