+ {state.error} +
+ ) : null} + + {optimistic.length === 0 ? ( +No notes yet. Add the first one.
+ ) : ( +
+ The form posts to a Server Action, so there is no client fetch handler and no client-side API layer. The new note
+ shows the instant you submit via useOptimistic, then reconciles against what the server returns. Tick
+ “simulate a failure” to watch the optimistic note revert and an error render in its place.
+
+ Three states share one flow. useActionState holds the confirmed list and the last error and exposes
+ the pending flag. useOptimistic overlays the in-flight note on top of that confirmed list, and React
+ discards the overlay automatically when the action settles, so a rejected write reverts on its own with no manual
+ rollback. useFormStatus reads the pending state from inside the form to disable the button. The
+ overlay is only a prediction: the server is still the source of truth, and on error the confirmed list never
+ moved.
+