Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteiTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Blazor forms can work alongside immutable application state, but the form’s editing model needs a stable object while the user is typing. EditContext tracks modified fields and validation messages for that editing session. If you replace the form’s model object during editing, Blazor creates a new EditContext, and that session’s tracking starts empty. A practical approach is to edit a stable draft, then create a new immutable state value when the draft passes validation.
Why replacing a form model can reset tracking
An EditForm can receive either a Model or an EditContext. The context holds form-session information, including which fields have changed and the current validation messages. Microsoft documents that when a different object instance is assigned to EditForm.Model, the form creates a new EditContext (Microsoft Learn: Blazor forms binding).
That behavior is distinct from whether your application state is mutable or immutable. The issue arises when an edit operation replaces the object being used by the form: the replacement starts a new form context, so field-modified and validation tracking from the previous context does not carry over. An immutable reducer that constructs a replacement state object on every keystroke can therefore conflict with the form’s expectation of a continuous editing session.
Use a stable draft, then update immutable state on submit
Keep a draft object for the duration of the form edit. Blazor input components can bind to its properties with @bind-Value; for example, InputText can bind to Model!.Id. A form can include DataAnnotationsValidator and ValidationSummary, and use OnValidSubmit for a handler that runs only when validation succeeds (Microsoft Learn: Blazor forms).
#1 Best Overall
- Initialize a draft. Create an editable instance from the current application-state value when the user begins editing.
- Bind the form to the draft. Keep that object instance in place as controls update its properties, allowing the same
EditContextto track the session. - Validate and commit. In the valid-submit handler, map the draft into a new immutable application-state value or dispatch an action that constructs one.
This is an architectural recommendation inferred from the documented model and context behavior, not a Microsoft-prescribed immutable-state rule. If the form model must be replaced during editing, manage the EditContext deliberately and account for its field and validation state beginning empty.
Stable draft versus replacing the model during editing
| Approach | EditContext tracking | Fit with immutable application-state updates | Implementation trade-off |
|---|---|---|---|
| Stable draft, immutable commit on valid submit | Preserves the current editing session’s modified-field and validation tracking while the draft instance remains stable. | Creates a new application-state value when the edit is committed. | Requires a draft and a mapping or dispatch step at submission. |
| Replace the form model during editing | A different model instance creates a new EditContext; modified-field and validation tracking starts empty. | Can follow replacement-style state updates during editing. | Requires deliberate management of context replacement and its reset effects. |
Keep child component parameters immutable with two-way binding
Forms are not the only place where immutability matters. A child component that changes a parameter directly can effectively mutate its parent’s state. Microsoft’s .NET 10 data-binding documentation advises avoiding direct parameter changes because they can interfere with change detection and cause extra render cycles. For a child parameter that should remain immutable, use paired @bind:get and @bind:set modifiers to accept changes through a callback instead (Microsoft Learn: Blazor data binding).
Rank #2
This lets the parent remain responsible for applying the update, while the child receives the current value and reports the proposed change. It is a component-level pattern; it does not remove the need to keep an EditForm’s editing model stable if you want one continuous form context.
Free tools Windows power users keep installed
One-click scans. No signup required.
Choose the right approach for custom inputs
For a custom form control, Microsoft recommends deriving from InputBase<TValue> unless a requirement prevents it. The base class provides common binding, callbacks, and validation integration, and the component must be used inside an EditForm. A fully custom input is also possible, but its implementation must handle binding, callbacks, and validation itself (Microsoft Learn: Blazor forms binding).
Quick Recap
Best Value
Rank #4
| Custom input approach | What it provides or requires | When it fits |
|---|---|---|
Derive from InputBase<TValue> |
Common binding, callbacks, and validation support; must be used within EditForm. |
When the standard form integration meets the control’s needs. |
| Implement input processing yourself | Your component is responsible for binding, callbacks, and validation. | When a specialized requirement prevents using the base class. |
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

