Deletion is the one operation you can’t undo. Always ask the user to confirm before deleting.
Backend (Python)
API Client (JS)
Copy
@app.delete("/api/users/{user_id}", status_code=204)def delete_user(user_id: int): user = find_user(user_id) if not user: raise HTTPException(status_code=404, detail="User not found") users.remove(user) # Returns nothing (204 No Content)
Copy
export async function deleteUser(id) { const response = await fetch(`${API_URL}/api/users/${id}`, { method: "DELETE", }); if (!response.ok) throw new Error(`HTTP ${response.status}`);}
Two states: confirming (are we showing the confirmation?) and deleting (is the API call in progress?). The user clicks Delete → sees “Yes, delete” / “Cancel” → confirms → item is removed.
.filter() creates a new array without the deleted item. This is the standard pattern for removing items from a list in React.
prev.filter(u => u.id !== userId) keeps every user whose ID does NOT match the deleted one. Simple, immutable, and correct. You’ll use this pattern alongside .map() for updates and [...prev, newItem] for creates.
// CREATE — add to the endsetUsers(prev => [...prev, newUser]);// UPDATE — replace the matching itemsetUsers(prev => prev.map(u => u.id === updated.id ? updated : u));// DELETE — remove the matching itemsetUsers(prev => prev.filter(u => u.id !== userId));
These three lines are the entire state management for a CRUD application. Memorize them — you’ll write them in every project.
All three patterns create new arrays instead of modifying the existing one. This is immutable state updates — React requires this to detect changes and re-render. Never use .push(), .splice(), or direct assignment on state arrays.