I have a state for my orders list. On the first update everything is working fine but when an update is made on the order in the database, my order list is updated but not triggering a re-render even using <...>
const [orders, setOrders] = useState([]); useEffect(() => { const unsubscribe = firebase.firestore().collection("Orders").orderBy("date", "desc").limit(parseInt(limit, 10)).onSnapshot((snapshot) => { let oldOrders = orders; let addedOrders = [] snapshot.docChanges().forEach((change) => { if (change.type === "added") { addedOrders.push({...change.doc.data(), id: change.doc.id }) } if (change.type === "modified") { oldOrders[oldOrders.findIndex(x => x.id === change.doc.id)] = {...change.doc.data(), id: change.doc.id } } if (change.type === "removed") { oldOrders.splice(oldOrders.findIndex(x => x.id === change.doc.id)) } }); if (addedOrders.length > 0) { oldOrders.unshift(addedOrders) } setOrders(...oldOrders); }); return () => { unsubscribe() } }, [limit]);
You are mutating the state.
let oldOrders = orders;
does not create a copy of array. It copies reference.setOrders(...oldOrders);
makes no sense. You are spreading array as arguments but setOrders
accepts 1 argument.setState
oldOrders.unshift(...addedOrders);
if you want to add multiple items not just a single array.Your code should look somewhat like this assuming the rest of your logic is correct.
useEffect(() => {
const unsubscribe = firebase
.firestore()
.collection("Orders")
.orderBy("date", "desc")
.limit(parseInt(limit, 10))
.onSnapshot((snapshot) => {
// use callback form to avoid relying on stale state
setOrders((orders) => {
let oldOrders = [...orders]; // create new array
let addedOrders = [];
snapshot.docChanges().forEach((change) => {
if (change.type === "added") {
addedOrders.push({ ...change.doc.data(), id: change.doc.id });
}
if (change.type === "modified") {
oldOrders[oldOrders.findIndex((x) => x.id === change.doc.id)] = {
...change.doc.data(),
id: change.doc.id,
};
}
if (change.type === "removed") {
oldOrders.splice(
oldOrders.findIndex((x) => x.id === change.doc.id)
);
}
});
if (addedOrders.length > 0) {
oldOrders.unshift(...addedOrders);
}
return oldOrders;
});
});
return () => {
unsubscribe();
};
}, [limit]);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.