编写大量不必要的 Firestore 读取操作的代码

Code making a lot of unnecessary Firestore Read Operations

您好,我目前正在制作一个博客,它使用 Firestore 来存储博客 posts,然后读取并显示在我的主页上。它还包括通过 Firebase 进行的身份验证。出于某种原因,我一直在达到每天 50k 次阅读的免费配额,即使只存储了一些文档并且很少刷新。该应用程序只能在我的本地硬件上使用。

阅读量应该在十几岁,但每次刷新页面最终都会有数千次。

我唯一一次真正连接到数据库是在主页上使用 UseEffect 时,所以肯定是那样,但我不确定我做错了什么。当我在依赖项中有 deletePost 时,它仍然具有相同的效果。

这是使用 UseEffect 并从 firestore 读取数据以显示数据的主页。

import React, { useState, useEffect } from 'react';
import {getDocs, collection} from "firebase/firestore";
import {db} from "../../services/firebase";
import "./Home.css";
import MultiActionAreaCard from '../../components/postCard/postCard';
import { Grid } from '@mui/material';


function Home({isAuth}) {
    const [postList, setPostList] = useState([]);
    const postsCollectionRef = collection(db, "Posts");

    useEffect(() => {
        const getPosts = async () => {
            const data = await getDocs(postsCollectionRef);
            setPostList(data.docs.map((doc) => ({...doc.data(), id: doc.id})));
        }
        getPosts();
    }, [ postsCollectionRef]);

    
    return (
        <div className='homePage'>
            <Grid container spacing={3}>
            {postList.map((post) => {
                return (
                    <Grid item xs={12} sm={6} md={4}>
                        <MultiActionAreaCard title={post.title} author={post.author.name} authorID={post.author.id} post={post.postText} isAuth={isAuth} id={post.id}/>
                    </Grid>
            )})}
            </Grid>
        </div>
    )
};

export default Home;

这是 MultiActionAreaCard 中的 deletePost 函数,用于连接到 firestore 并删除 post 以防万一。仅在单击删除按钮时调用。

   const deletePost = async (id) => {
    const postDoc = doc(db, "Posts", id )
    await deleteDoc(postDoc);

如果您希望我包含任何其他内容以帮助大家帮助我,请告诉我!它不会让我 post 图片,因为我没有 10 个声誉,但大多数时候它说我有 51k 次读取,只有 2-3 次写入和删除。因此,除了读取之外,其他指标都在正常工作。

没有看到这个 Home 组件是什么或如何渲染的,也没有看到你的应用程序可能正在使用你的 firestore 做的任何其他事情,似乎很可能因为 postsCollectionRef 是任何时候这个 Home 组件渲染这也在每个渲染上触发 useEffect 钩子回调。

如果没有其他引用 postsCollectionRef,则将其移动到外部组件 进入 useEffect 的回调范围,因此可以将其作为外部依赖项删除。这允许您使用空依赖项,因此 useEffect 挂钩回调仅在 Home 组件安装时调用一次。

const [postList, setPostList] = useState([]);

useEffect(() => {
  const postsCollectionRef = collection(db, "Posts");

  const getPosts = async () => {
    const data = await getDocs(postsCollectionRef);
    setPostList(data.docs.map((doc) => ({...doc.data(), id: doc.id})));
  }

  getPosts();
}, []);

如果另一方面 postsCollectionRef 在其他地方引用,那么再次,要么移动它 组件之外或记住它的值,因此它是从渲染到渲染的稳定参考。

const [postList, setPostList] = useState([]);
const postsCollectionRef = useRef(collection(db, "Posts"));

useEffect(() => {
  const getPosts = async () => {
    const data = await getDocs(postsCollectionRef.current);
    setPostList(data.docs.map((doc) => ({...doc.data(), id: doc.id})));
  }

  getPosts();
}, []);

// use postsCollectionRef.current elsewhere for accesses