skip to Main Content

i have made a CRUD app using firebase and react mostly on my own,
`

  const userEmail = localStorage.getItem("email");
  const [modalOpen, setModalOpen] = useState(false);
  const [rows, setRows] = useState([]);
  const [rowToEdit, setRowToEdit] = useState(null);

  const getData = async () => {
    console.log("no. of getData calls");
    const docRef = collection(db, "bunkManager",`${userEmail}`,"course");
    const dataDB = await getDocs(docRef);
    const allData = dataDB.docs.map(val => ({course:val.id, ...val.data(),}));
    setRows(allData);
  };

    useEffect(() => {
    getData();
    console.log("useEffect");
  },[]);

  const handleSubmit = async (newRow) => {
    await setDoc(doc(db,"bunkManager", userEmail, "course",newRow.course), {
      bunkedHours: newRow.bunkedHours,
      totalHours: newRow.totalHours
    });
  };

  const handleEditRow = (index) => {
    setRowToEdit(index);

    setModalOpen(true);
  };

  const handleDeleteRow = async (course) => {
    await deleteDoc(doc(db, "bunkManager", userEmail, "course",course));
  };

  return (
    <>
    <Table rows={rows} deleteRow={handleDeleteRow} editRow={handleEditRow}/>
    <button className='submit_btn' onClick={() => setModalOpen(true)}>Add Course</button>
    {modalOpen && <Modal closeModal={() => {setModalOpen(false); setRowToEdit(null);}} onSubmit={handleSubmit} defaultValue={rowToEdit !== null && rows[rowToEdit]}/>}
    </>
  )
}`

the console log inside useEffect is being infinitely called, i didnt notice it untill my app stopped working due to firebase limit on read.

im using useEffect to get data whenever theres an update to the table, but if its gonna infinitely call getData(); i cant have this app running in long time,

i tried my best to find answers but i couldnt :(, im sorry if there are multiple similar posts with similar problem

4

Answers


  1. You have given the state rows as dependency array to useEffect and in useEffect you are calling api to getData and then set the state setRows again which changes row state again and useEffect runs indefinitely due to that reason. If you want to run useEffect only once do something like this:-

    useEffect(() => { getData(); }, []);
    

    I hope it makes sense!

    Login or Signup to reply.
  2. getData sets rows.
    When rows is set useEffect triggers.
    useEffect calls getData.
    getData sets rows.
    Etc. etc.

    You’ve set up an infinite loop

    Login or Signup to reply.
  3. You add rows in the dependencies array of the useEffect but in the useEffect you also make changes to rows by calling setRows(allData). This creates an infinite loop since the dependencies of the useEffect hook always change at every render.

    Login or Signup to reply.
  4. Second argument to useEffect should be [userEmail] instead of [rows], You can read more about it here. To make it even better you can use [db, userEmail] and code depends on those two variables as arguments
    The issue is that you have placed destination variable instead of in the dependencies that results into infinite look

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search