0

I'm building a react app that lets you display members from a database, add new members and delete them. For some reason when the app is running I'm getting 50k reads in just a few minutes even tho I'm the only one using this app and the collection contains only a few KB of data. Firebase usage monitor:

import { useState, useEffect} from "react";
import { db } from "../utils/firebase-config";
import moment from "moment/moment";
import {
  collection,
  getDocs,
  addDoc,
  deleteDoc,
  doc
} from "firebase/firestore";

export default function MemberPage() {

    const membersCollectionRef =  collection(db, "members");

    // Create new member
    const [newName, setNewName] = useState("");
    const [newSurname, setNewSurname] = useState("");
    const [newNickname, setNewNickname] = useState("");
    const [newPhone, setNewPhone] = useState("");
    const [newEmail, setNewEmail] = useState("");
    const [newDateOfBirth, setNewDateOfBirth] = useState("");
    const [renderKey, setRenderKey] = useState(0);

    const createMember = async () => {
        await addDoc(membersCollectionRef, { 
            name: newName,
            surname: newSurname,
            nickname: newNickname,
            phone: newPhone,
            email: newEmail,
            dateOfBirth: newDateOfBirth,
            balance: 0
        });

        // Clear input fields values and refresh the component
        setNewName('');
        setNewSurname('');
        setNewNickname('');
        setNewPhone('');
        setNewEmail('');
        setNewDateOfBirth('');
        setRenderKey((prevKey) => prevKey + 1);
      };
    // Create new member

    // Read members from DB
    const [members, setMembers] = useState([]);
    
    const getMembers = async () => {
        const dataSnap = await getDocs(membersCollectionRef);
        setMembers(dataSnap.docs.map((doc) => ({ ...doc.data(), id: doc.id})));
    };

    useEffect(() => {
        getMembers();
    }, [membersCollectionRef, renderKey]);
    // Read members from DB

    // Delete members from DB
    const deleteMember = async (id) => {
        const memberDoc = doc(db, "members", id);
        await deleteDoc(memberDoc);
      };
    // Delete members from DB
{members.map((member) => { return (
                                <tr key={member.id}>
                                    <td>{member.name.toString()}</td>
                                    <td>{member.surname.toString()}</td>
                                    <td>{member.nickname.toString()}</td>
                                    <td>{member.phone.toString()}</td>
                                    <td>{member.email.toString()}</td>
                                    <td>{moment(Date(member.dateOfBirth.toString())).format('D/MM/YYYY')}</td>
                                    <td>{member.balance.toString()}</td>
                                    <td>
                                        <IconButton 
                                            aria-label="delete" 
                                            size="large" 
                                            color='error' 
                                            onClick={() => {
                                                deleteMember(member.id);
                                                }}>
                                            <DeleteIcon fontSize="inherit"/>
                                        </IconButton>
                                    </td>
                                    <td>update</td>
                                </tr>
                            );
                        })}
<input 
                            type="text" 
                            value={newName}
                            placeholder="Imię"
                            onChange={(event) => {
                                setNewName(event.target.value);
                            }}
                        />
                        <input 
                            type="text"
                            value={newSurname}
                            placeholder="Nazwisko"
                            onChange={(event) => {
                                setNewSurname(event.target.value);
                            }}
                        />
                        <input 
                            type="text" 
                            value={newNickname}
                            placeholder="Ksywka"
                            onChange={(event) => {
                                setNewNickname(event.target.value);
                            }}
                        />
                        <input 
                            type="tel" 
                            value={newPhone}
                            placeholder="Telefon"
                            onChange={(event) => {
                                setNewPhone(event.target.value);
                            }}
                        />
                        <input 
                            type="email" 
                            value={newEmail}
                            placeholder="E-mail"
                            onChange={(event) => {
                                setNewEmail(event.target.value);
                            }}
                        />
                        <input 
                            type="date" 
                            value={newDateOfBirth}
                            placeholder="Data urodzenia"
                            onChange={(event) => {
                                setNewDateOfBirth(event.target.value);
                            }}
                        />
                    </div>
                    <div className="add-user">
                        <IconButton 
                            aria-label="add-user" 
                            size='large' 
                            color='primary' 
                            onClick={createMember}>
                            <PersonAdd sx={{fontSize: 60}}/>
                        </IconButton>
                    </div>

What's the problem in my code? Can open usage monitor cause this many reads?

  • 1
    I think you are creating a new instance of `const membersCollectionRef = collection(db, "members");` on every render causing your useEffect to fire every render. Try moving the instantiation of `membersCollectionRef` outside of your component. Basically move it up two lines. – Scott Z May 03 '23 at 01:34
  • 1
    ... and remove it from the effect hook dependencies. I'm surprised your linter isn't warning you about the infinite loop in your effect hook – Phil May 03 '23 at 01:38

1 Answers1

-1

When state is changes, it always re-render. I suggest you to take all form related, including the set state into another component. I use react-hook-form all the time for all my project.

Nani
  • 65
  • 6