我已经构建了一个自定义钩子:
const useFirestoreCollection = async (collectionName) => { const [documents, setDocuments] = useState([]); useEffect(() => { const fetchData = async () => { const querySnapshot = await getDocs(collection(db, collectionName)); const documentsData = []; querySnapshot.forEach((doc) => { documentsData.push({ id: doc.id, ...doc.data(), }); }); setDocuments(documentsData); }; fetchData(); }, []); return documents; };
我可以在我的组件中像这样使用它:
const [myData, setMyData] = useState([]); useFirestoreCollection('registeredUsers') .then((data) => { setMyData(data); // Data Access }) .catch((error) => { console.log(error); // Error });
我还可以删除自定义挂钩中的异步:
const useFirestoreCollection = (collectionName) => { <- ASYNC DELETED const [documents, setDocuments] = useState([]); useEffect(() => { const fetchData = async () => { const querySnapshot = await getDocs(collection(db, collectionName)); const documentsData = []; querySnapshot.forEach((doc) => { documentsData.push({ id: doc.id, ...doc.data(), }); }); setDocuments(documentsData); }; fetchData(); }, []); return documents; };
...并在我的组件中像这样使用它:
const myData = useFirestoreCollection('registeredUsers')
我试图找出最好的方法,但没能做到。
什么时候应该在钩子中使用 async 关键字,什么时候不应该使用?
我从未见过钩子应该是异步的情况。该钩子现在返回一个承诺,而不仅仅是您希望组件使用的 state 和 setState 函数。这将是一个主要的反模式,并使钩子的简单性变得非常复杂。
如果您需要在挂钩中使用异步/等待功能,则可以在其中声明异步函数。就像你所做的那样。
第二种方法显然是执行此操作的正确方法。
在第一种情况下,使钩子异步是没有用的,因为钩子中没有任何异步内容,仅在
useEffect
内部。这使得它更难以使用并且使您重复状态。