从 Firestore 获取用户数据并将其保存到状态 - React

Getting user data from Firestore and saving it to state - React

我想将用户数据保存到状态中,但由于某些原因无法正常工作

我创建这个函数是为了从 Firestore 获取数据,然后从登录组件中的 handleSubmit 函数调用它

function getUserData() {
   return db
     .collection("customers")
     .doc(currentUser.uid)
     .get()
     .then((doc) => {
       setUserData(doc.data());
     });
 }

如果我在调用函数后控制台记录 userData,我得到未定义的,但如果我 console.log(doc.data()),我得到正确的对象。任何关于我做错了什么的提示都将不胜感激。

这是在登录表单组件中调用函数的 handleSubmit 函数:

const onSubmit = async (values) => {
    try {
      setError("");
      setLoading(true);
      await login(values.email, values.password);
      authenticateUser();

      await getUserData();

      console.log(userData);
      history.push("/");
    } catch {
      setError("Failed to log in");
    }

    setLoading(false);
  };```

我假设 setUserData 是一个 useState 挂钩函数。如果是这样,那么它就是一个异步函数。这就是为什么您在控制台记录 doc.data() 而不是 userData 时看到数据的原因。

如果您想等到您的 userData 存在后再导航到 ('/'),​​您可以执行以下操作。我会删除 getUserData 前面的 await,因为它什么也没做。

useEffect(()=>{
  if (user) history.push("/")
},[user]);

任何 setState 函数都是异步的,因此在它之后记录不会显示值,因为它仍在更新状态。要看到实际的变化,您需要一个效果。由于 userData 是一个对象,因此常规 useEffect 将不起作用。你需要的是观察对象变化的东西。这就是 useDeepCompareEffect by Kent 的用武之地。

import useDeepCompareEffect from 'use-deep-compare-effect'
...

const [userData, setUserData] = useState();
...
// This effect will do what you want when userData changes
useDeepCompareEffect(()=> { 
  if(userData) {
  // do whatever you want here if userData is defined or whatever logic you looking for
  history.push("/");
  }
}, [userData])