Reputation: 304
I am making a small application for writing words, using a Firestore Cloud for data storage. I use onSubmit
to send data to Firestore for storage.
Everything works and is saved to the cloud, but the data is not updated on the page, for which you need to reload the page and after that the data will already be updated.
How can I solve this problem, do I need to render a new array every time and get data from the server in order to update the data (fetchProduct
), or is it possible in some other way?
function Menu() {
const [data, setData] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const { user } = UserAuth();
const fetchProduct = async () => {
const ref = collection(db, "langcards-db");
const q = query(ref, where("author", "==", user.uid));
const querySnapshot = await getDocs(q);
const arr = [];
querySnapshot.forEach((doc) => {
arr.push({
...doc.data(),
id: doc.id,
});
});
setData(arr);
setIsLoading(false);
};
useEffect(() => {
if (user) {
fetchProduct();
} else {
setData([]);
setIsLoading(false);
}
}, []);
useEffect(() => {
if (user) {
fetchProduct();
} else {
setData([]);
setIsLoading(false);
}
}, [user]);
const onSubmit = async (e) => {
e.preventDefault();
let rw = word.replace(/\s/g, "");
let rt = translate.replace(/\s/g, "");
if (rw.length >= 1 && rt.length >= 1) {
setWarn(false);
await addDoc(collection(db, "langcards-db"), {
word: word,
translate: translate,
note: note,
category: "category",
author: user.uid,
});
setWord("");
setTranslate("");
setNote("");
console.log(data)
} else {
setWarn(true);
}
};
return (
<div className="main-inner">
{isLoading ? (
<Loader />
) : (
<div className="content">
<Routes>
<Route
path="addcard"
element={
<AddCard
onChangeWord={onChangeWord}
onChangeNote={onChangeNote}
onChangeTranslate={onChangeTranslate}
onSubmit={onSubmit}
word={word}
translate={translate}
note={note}
warn={warn}
resetFormAdd={resetFormAdd}
/>
}
/>
<Route
path="saved"
element={<Saved data={data} setData={setData} />}
/>
</Route>
</Routes>
</div>
);
}
export default Menu;
Upvotes: 0
Views: 55
Reputation: 313
For this problem you should not use getDocs
but onSnapshot
which listens for changes in the data. Also, this way you can update the state directly and don`t have to create a new array each time. Then you can directly refer to .data
when accessing an entry from the data state.
useEffect(() => {
const ref = collection(db, "langcards-db");
const q = query(ref, where("author", "==", user.uid));
const unsubscribe = onSnapshot(q, { includeMetadataChanges: true }, (querySnapshot) => {
setData([]); // Empty state
querySnapshot.forEach((doc) => {
// Do something with your data (append it to the data array like before)
setData(old => {...old, {"id" : doc.id, "data" : doc.data()});
});
});
return () => { unsubscribe(); };
}, [])
In this doc you can read more about how to fetch data from your firestore.
Upvotes: 1