我已经建立了一个自定义钩子:
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
});
我也可以删除我的自定义钩子中的async:
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关键字,什么时候不应该?
2条答案
按热度按时间bvjveswy1#
我从来没有见过一个钩子是异步的情况。这个钩子现在返回一个承诺,而不是你希望你的组件使用的简单的state和setState函数。这将是一个主要的反模式&使钩子的简单性变得非常复杂。
如果你需要在钩子中使用async/await功能,你可以在里面声明一个async函数,就像你以前做的那样。
第二种方法显然是正确的方法。
uujelgoq2#
在第一种情况下,让钩子异步是无用的,因为没有任何异步直接进入钩子,只有在
useEffect
内部。这使得它更难使用,并使您重复状态。