useEffect 多次渲染,即使数据没有变化
useEffect rendering multiple times even when data is not changing
如果依赖项数组为空,此 useEffect 将渲染一次,但如果我将 folderRef 放入依赖项数组,则会渲染多次。我只想在添加或删除某个文件夹时渲染组件。请帮忙
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;
我觉得最有可能你的useState函数是这样的
const[folderRef , setFolders]=useState(Your Initial Value);
如果是这种情况,那么你什么时候执行
useEffect(() => {
setFolder(Setting Anything Here)
....
},[folderRef])
React 会开始无限循环,因为每次您使用 setFolder 时,FolderRef 都会更新,并且 useEffect 会再次被强制 运行,并且不会停止。
使用类似
的东西
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 }
)
您重新声明 folderRef
每个渲染周期,因此如果您将其包含在 useEffect
挂钩的依赖项数组中,它将触发渲染循环。
如果您没有在组件中的其他任何地方引用 folderRef
然后将其移动 到 useEffect
挂钩回调中以将其作为外部删除依赖性。
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();
}, []);
或者将其存储在 React ref 中,以便可以安全地引用它作为稳定的引用。
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]);
更新
我了解到您正在更新应用中其他地方的 folders
集合,并希望此组件“侦听”这些更改。为此,您可以实现一个 onSnapshot
侦听器。
它可能类似于以下内容:
const [folders, setFolders] = useState([]);
useEffect(() => {
const unsubscribe = onSnapshot(
collection(db, "folders"),
(snapshot) => {
const folderData = [];
snapshot.forEach((doc) => {
folderData.push({
id: doc.id,
data: doc.data(),
});
});
setFolders(folderData);
},
);
// Return cleanup function to stop listening to changes
// on component unmount
return unsubscribe;
}, []);
如果依赖项数组为空,此 useEffect 将渲染一次,但如果我将 folderRef 放入依赖项数组,则会渲染多次。我只想在添加或删除某个文件夹时渲染组件。请帮忙
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;
我觉得最有可能你的useState函数是这样的
const[folderRef , setFolders]=useState(Your Initial Value);
如果是这种情况,那么你什么时候执行
useEffect(() => {
setFolder(Setting Anything Here)
....
},[folderRef])
React 会开始无限循环,因为每次您使用 setFolder 时,FolderRef 都会更新,并且 useEffect 会再次被强制 运行,并且不会停止。
使用类似
的东西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 }
)
您重新声明 folderRef
每个渲染周期,因此如果您将其包含在 useEffect
挂钩的依赖项数组中,它将触发渲染循环。
如果您没有在组件中的其他任何地方引用 folderRef
然后将其移动 到 useEffect
挂钩回调中以将其作为外部删除依赖性。
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();
}, []);
或者将其存储在 React ref 中,以便可以安全地引用它作为稳定的引用。
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]);
更新
我了解到您正在更新应用中其他地方的 folders
集合,并希望此组件“侦听”这些更改。为此,您可以实现一个 onSnapshot
侦听器。
它可能类似于以下内容:
const [folders, setFolders] = useState([]);
useEffect(() => {
const unsubscribe = onSnapshot(
collection(db, "folders"),
(snapshot) => {
const folderData = [];
snapshot.forEach((doc) => {
folderData.push({
id: doc.id,
data: doc.data(),
});
});
setFolders(folderData);
},
);
// Return cleanup function to stop listening to changes
// on component unmount
return unsubscribe;
}, []);