Skip to main content

Two steps: load, then save

Updating a record means: load the current data into a form, let the user edit it, then send the changes back to the API.
The companion repo keeps update simpler and reuses UserCreate for PUT /api/users/{id} (full replacement). This lesson introduces a separate UserUpdate model with optional fields to teach the common “partial update shape” pattern.

The edit form component

The key difference from the Create form: initialize state with the existing data.
Notice:
  • State initialized from user prop — form starts with current values
  • onSave callback — parent receives the updated object from the API
  • onCancel callback — lets the user exit edit mode without saving
  • Cancel is type="button" — prevents it from submitting the form

Toggle between view and edit mode

The parent component switches between displaying data and showing the edit form:
The state update uses .map() — replace the old user with the updated one, leave everything else unchanged.
prev.map(u => u.id === updatedUser.id ? updatedUser : u) is the standard pattern for updating one item in a list. It creates a new array where only the matching item is replaced. You’ll use this pattern constantly.

Optimistic vs pessimistic updates

Pessimistic (wait for server, then update UI):
Optimistic (update UI immediately, roll back on error):
Start with pessimistic updates. They’re simpler and always correct. Only switch to optimistic updates for actions where the slight delay feels sluggish — like toggling a checkbox or liking a post.

What’s next?

You can create, read, and update. The last CRUD operation: deleting records with confirmation.

Delete operation

Remove records with confirmation and proper error handling