Data Handling
This guide covers how the editor decides when to save, and how to hook into changes, saves, and validation so your app can track or react to what the user is doing.
The draft model
The editor never edits your data in place. When you pass an object to values, the editor deep-copies it into an internal draft and every field writes to that draft, not to your original object. Your values stays untouched until a save happens.
Two things follow from this:
- Changes are a diff. The editor compares the draft against the copy it started with and tracks only the keys that actually differ. That list of changed keys is what you get as
ev.changesinonSave, and it affects what gets validated and written back. - Saving is a separate from editing. Editing updates the draft; saving is when the draft's changes are written back and
onSavefires. Whether that happens on every keystroke or only on an explicit action is controlled byautoSaveprop.
Passing a new object to values resets the draft, so swapping the bound record (for example, selecting a different row) discards any unsaved edits and starts fresh.
Auto-save vs. manual save
autoSave controls the save trigger. With autoSave={true}, every valid field change writes back immediately and fires onSave. With autoSave={false} (the default for Editor), changes wait until the user clicks a save button on toolbar (item with id: "save") and only after that the onSave fires.
{/* modifications are applied on each change */}
<Editor items={items} autoSave={true} />
{/* modifications are applied on `save` button, default */}
<Editor items={items} autoSave={false} />
Detecting field changes
onChange fires on every field edit with the changed key, the new value, and the running map of unsaved changes:
import { Editor } from "@svar-ui/react-editor";
function onChange(ev) {
console.log(`field ${ev.key} was changed to ${ev.value}`);
console.log("all not saved changes", ev.update);
}
<Editor items={items} onChange={onChange} />
This is the hook for tracking modifications or highlighting unsaved state.
Driving dependent fields
ev.update is the live draft the editor is about to diff and save, so mutating it inside onChange lets one field reset or recompute another before the change is committed. For example, clearing the selected city whenever the country changes:
import { Editor } from "@svar-ui/react-editor";
function onChange(ev) {
if (ev.key === "country") {
ev.update.city = "";
}
}
<Editor items={items} values={values} onChange={onChange} />
The editor applies the mutated draft, so the dependent field updates in the same edit cycle.
Detecting save actions
onSave fires when changes are actually persisted - on every change with autoSave={true}, or on the Save action with autoSave={false}. It receives the list of changed keys and the current values snapshot:
import { Editor } from "@svar-ui/react-editor";
function onSave(ev) {
console.log("changed values", ev.changes);
console.log("latest data snapshot", ev.values);
}
<Editor items={items} onSave={onSave} />
Use it to save the updated record back to store or backend.
Detecting validation results
onValidation fires whenever the validation result changes, with a map of field errors (or null when the form is valid):
import { Editor } from "@svar-ui/react-editor";
function onValidation(ev) {
if (ev.errors) {
for (const key in ev.errors) {
console.log(`"${key}" failed: ${ev.errors[key].errorType}`);
}
} else {
console.log("validation is ok");
}
}
<Editor items={items} onValidation={onValidation} />
errorType is "required" for an empty required field or "validation" for a failed custom rule.
Required fields and custom validation rules
Set required: true on an item to block saving until it has a value:
const items = [
{ comp: "text", key: "name", required: true }
];
For more complicated check attach a validation(value) rule and an optional validationMessage to show when it fails:
const items = [
{
comp: "text",
key: "name",
label: "Name",
validation: val => /^[a-zA-Z]+$/.test(val),
validationMessage: "wrong name format"
}
];

validation rule need to return true for a valid value and false otherwise.