Here's a bug I've shipped more than once: you edit a user on page 3 of an admin table, save, and the table jumps back to page 1. The edit worked. The user just isn't visible anymore, and for a second you wonder whether it worked at all.
The fix in my starter kit's Users page is one argument: after closing the modal, call fetchUsers(meta.current_page) instead of fetchUsers(1). The modal closes, and the table reloads the page the admin was already looking at, with the fresh data from the server. The edited row is right there, updated. The newly added user shows up too, since the list is ordered newest-first — and if pagination shifted because of the add, the server's meta in the response corrects the pager anyway, because fetchUsers stores res.data.meta alongside the rows.
Delete follows the same rule: after client.delete('/users/' + id), call fetchUsers(meta.current_page) again. Same page. If deleting the last row on a page leaves it empty, that's a real edge case — the honest version of this code would step back a page when the response comes back empty — but the common case, which is what a starter kit should get right first, is staying put.
Why refetch at all, instead of updating the local row optimistically? Because the server is the source of truth for this table, and the list endpoint is cheap. The create response returns the new user, the update response returns the updated user, but patching those into a paginated, sorted list by hand means re-implementing the server's ordering and pagination in the client. One refetch gets you the server's ordering, the correct page meta, and every other admin's concurrent changes, for the price of one GET.
There's a discipline hiding in this: after a mutation, don't guess at the new state — ask for it. Optimistic updates are a performance optimisation, and they're worth it when a list is slow or a mutation is expensive. For an admin table over a local API, the refetch is fast, simple, and never wrong. I save the cleverness for places where it pays.
Staying on the same page sounds trivial. But it's the difference between an admin who trusts the tool — save, see it change, move on — and one who keeps re-navigating to check their own work. Small respect for the user's attention, coded as one argument.
This Users page, the paginated API behind it, and the whole admin panel ship in my Laravel + React SaaS Starter Kit — https://kamranofficial.gumroad.com/l/mhekoig — a $19 one-time boilerplate with Sanctum auth and role-based access, so you don't rebuild this table from scratch.
Top comments (0)