This useEffect is rendering one time if dependency array is empty but multiple times if i put folderRef in dependency array. I want to render the component only when I add or delete some folder. Please Help
import React, { useState, useEffect , useRef } from "react";
import { db } from "../firebase";
import { collection, getDocs } from "firebase/firestore";
import FolderData from "./FolderData";
function ShowFolder(props) {
const [folders, setFolders] = useState([]);
const folderRef = useRef(collection(db, "folders"));
useEffect(() => {
const getData = async () => {
const data = await getDocs(folderRef.current);
const folderData = data.docs.map((doc) => {
return { id: doc.id, data: doc.data() };
});
console.log(folderData);
setFolders(folderData);
};
getData();
}, [folderRef]);
return (
<div className="container md:px-4 mx-auto py-10">
<div className="md:grid lg:grid-cols-6 md:grid-cols-3 mlg:grid-cols-3 md:gap-10 space-y-6 md:space-y-0 px-1 md:px-0 mx-auto">
{folders.map((folder) => {
return (
<div key={folder.id}>
{folder.data.userId === props.userId && (
<div>
<FolderData key={folder.id} folder={folder} />
</div>
)}
</div>
);
})}
</div>
</div>
);
}
export default ShowFolder;
CodePudding user response:
You redeclare folderRef each render cycle, so if you include it in the useEffect hook's dependency array it will trigger render looping.
If you don't refer to folderRef anywhere else in the component then move it into the useEffect hook callback to remove it as an external dependnecy.
const [folders, setFolders] = useState([]);
useEffect(() => {
const folderRef = collection(db, "folders");
const getData = async () => {
const data = await getDocs(folderRef);
const folderData = data.docs.map((doc) => {
return { id: doc.id, data: doc.data() };
});
console.log(folderData);
setFolders(folderData);
};
getData();
}, []);
Or store it in a React ref so it can be safely referred to as a stable reference.
const [folders, setFolders] = useState([]);
const folderRef = useRef(collection(db, "folders"));
useEffect(() => {
const getData = async () => {
const data = await getDocs(folderRef.current);
const folderData = data.docs.map((doc) => {
return { id: doc.id, data: doc.data() };
});
console.log(folderData);
setFolders(folderData);
};
getData();
}, [folderRef]);
CodePudding user response:
I think most Probably your useState function is like
const[folderRef , setFolders]=useState(Your Initial Value);
if this is the case then when ever you perform
useEffect(() => {
setFolder(Setting Anything Here)
....
},[folderRef])
React starts an infinity loop coz every time you use setFolder the FolderRef gets updated and the useEffect is forced to run again and it won't Stop .
use something like
const[folderRef , setFolders]=useState(Your Initial Value);
const[isLoading, setIsLoading]=useState(true);
useEffect(() => {
setFolder(Setting Anything Here)
setIsLoading(false)
....
},[])
...
return (
{ isLoading ? "Run the code you wanna run " : null }
)
