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
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:-
I hope it makes sense!
getData sets rows.
When rows is set useEffect triggers.
useEffect calls getData.
getData sets rows.
Etc. etc.
You’ve set up an infinite loop
You add
rows
in the dependencies array of theuseEffect
but in theuseEffect
you also make changes torows
by callingsetRows(allData)
. This creates an infinite loop since the dependencies of theuseEffect
hook always change at every render.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 argumentsThe issue is that you have placed destination variable instead of in the dependencies that results into infinite look