簡體   English   中英

如何在“setUsername”場景中最小化 firestore 讀取?

[英]How can I minimize firestore reads in the "setUsername" scenario?

我現在創建的代碼正在運行,但我認為它在某種程度上不是最理想的,因為它對許多數據庫讀取都是如此 據我了解,“onAuthStateChange”可以理解為 useEffect 掛鈎,只要用戶身份驗證就會調用它state 更改(登錄、注銷)。 每當發生這種情況時,都應檢查數據庫以查找用戶選擇的用戶名。 但是,如果我看一下控制台,docSnap 會被記錄很多次,這對我來說表明 function 比用戶登錄/注銷時更頻繁地被調用。

在此處輸入圖像描述

上下文組件

import { createContext } from "react/cjs/react.production.min";
import { onAuthStateChanged } from "firebase/auth";
import { doc, getDoc } from "firebase/firestore";
import { auth,db } from "./firebase";
import { useState, useEffect } from "react";

export const authContext = createContext({
  user: "null",
  username: "null",
});

export default function AuthenticationContext(props) {
  const [googleUser, setGoogleUser] = useState(null);
  const [username, setUsername] = useState(null);
  const [userID, setUserID] = useState(null);

  onAuthStateChanged(auth, (user) => {
    if (user) {
      setGoogleUser(user.displayName);
      setUserID(user.uid);
      getUsername();
    } else {
      setGoogleUser(null);
    }
  });


    const getUsername = async () => {
      const docRef = doc(db, `users/${userID}`);
      const docSnap = await getDoc(docRef);
      if(docSnap.exists()){
        setUsername(docSnap.data().username);
      }
      else{
        setUsername(null);
      }
    };
  

  return (
    <authContext.Provider value={{ user: googleUser, username: username }}>
      {props.children}
    </authContext.Provider>
  );
}

更重要的是,當我使用 google 登錄並提交用戶名時,組件不會被重新評估 - 因此需要刷新才能使所有更改生效,這與我沒有更新 state 在登錄頁面的submitHandler。 如果您對我如何更專業地做到這一點有一些想法,請告訴我。 先感謝您!

在登錄頁面提交處理程序

const submitHandler = async (event) => {
    event.preventDefault();
    console.log(auth.lastNotifiedUid);
    await setDoc(doc(db, "users", auth.lastNotifiedUid), {
      displayName: user,
      username: username,
    });
    await setDoc(doc(db, "usernames", username), { uid: auth.lastNotifiedUid });
  };

正如 Dharmaraj 的評論中所指出的,您設置了對身份驗證 state 的多個訂閱。這是因為您在組件主體中調用onAuthStateChanged ,所以它會在每次渲染時執行。

為避免這種情況,您應該將 function 包裝在useEffect中,以便您僅訂閱組件安裝,並取消訂閱卸載:

export default function AuthenticationContext(props) {
  /* ... */
  React.useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (user) => { /* ... */ });
    return unsubscribe;
  }, []);
  /* ... */
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM