firebase 如何初始化react状态而不引起无限循环

xpszyzbs  于 2023-06-24  发布在  React
关注(0)|答案(1)|浏览(87)
const [dataIn, setDataIn] = useState<skillData[] | any>([]);

console.log("event loop");  
if(dataIn.length === 0) {
    console.log("updating data");
    const db = getFirestore(firebaseApp);
    const tempData : any = [];
    const data = await getDocs(collection(db, "MainWebsiteSkillsData"))
    data.forEach(elm => {
        tempData.push({...elm.data(), key : elm.id});
    });
    setDataIn(tempData);
} else {
    console.log("data already updated");
}

所以,我试图从firestore获取一些数据,并将其转换为数组并保存到状态,但所有的实现都会导致不同的问题。
像这样直接添加它会导致一个无限循环,而将它添加到useEffect块中不会更新状态。
无论哪种方式,有没有办法做到这一点,而不会导致无限循环?为什么国家没有更新?我读到一些关于每次重新渲染的闭包不一样的东西,但我使用了一个const变量来确保它持续存在。我甚至使用了其他线程建议的临时变量,但状态仍然没有更新。

osh3o9ms

osh3o9ms1#

我会创建一个firebaseApp.ts来存储所有初始数据。

const firebaseConfig = {
  apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
  authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
  projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
  storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
  appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
  measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID,
};

const app = !getApps().length ? initializeApp(firebaseConfig) : getApp(); //prevent initializeApp() from being called multiple times
const firestore = getFirestore(app);
const auth = getAuth(app);
const storage = getStorage(app);

export { app, firestore, auth, storage };

我不会使用任何类型。

const [dataIn, setDataIn] = useState<skillData[] | null>([]);

获取数据

useEffect(() => {
  async function fetchData() {
    const docRef = collection(firestore, "MainWebsiteSkillsData");
    const q = query(
      docRef,
      where("type", "==", "apple"),
      orderBy("createdAt", "desc"),
      limit(10)
    ); //you can set some options here
    //if no options, just replace the q to docRef
    try {
      const querySnapshot = await getDocs(q);
      const data = querySnapshot.docs.map((doc) => {
        const rawDocData = doc.data();
        //I prefer to create a zod.js object for checking valid data
        const docData = zodSchema.safeParse(rawDocData);
        if (docData.success) {
          return {...docData.data, key: doc.id} //add key value
        }
      });
      const finalProduct = data.flatMap((f) => (f ? [f] : [])); //remove undefined
      setDataIn(finalProduct)
    } catch(error) {
        console.log("Error: ", error)
    }
    return null
  }

  fetchData()
}, []);

相关问题