Bug Report
Problem 1 — Math.random() used as table row key
// Invoices.jsx
<TableRow key={`${Math.random()}`}>
Using a random value as a React key tells React that every row is a new element on every render. This causes the entire table body to unmount and remount on every state change, which:
- Destroys any focused/hovered cell state
- Breaks animations and transitions
- Forces unnecessary DOM churn for all 13 visible rows on each page or data update
Fix: use the stable invoice.uid that is already present on each item.
Problem 2 — .reverse() mutates the original array
// Invoices.jsx useEffect
setInvoices(data?.invoices.reverse() || []);
Array.prototype.reverse() mutates the array in place. Because data.invoices is a reference held by the useData hook, calling .reverse() on it permanently reverses the shared array. The next render reverses it again, causing invoices to flip order back and forth on each re-render.
Fix: shallow-copy before reversing: [...data.invoices].reverse()
Affected file
zk-medical-billing-tracker/src/pages/Invoices.jsx
Bug Report
Problem 1 —
Math.random()used as table row keyUsing a random value as a React key tells React that every row is a new element on every render. This causes the entire table body to unmount and remount on every state change, which:
Fix: use the stable
invoice.uidthat is already present on each item.Problem 2 —
.reverse()mutates the original arrayArray.prototype.reverse()mutates the array in place. Becausedata.invoicesis a reference held by theuseDatahook, calling.reverse()on it permanently reverses the shared array. The next render reverses it again, causing invoices to flip order back and forth on each re-render.Fix: shallow-copy before reversing:
[...data.invoices].reverse()Affected file
zk-medical-billing-tracker/src/pages/Invoices.jsx