Fields
Formix models form state as field references created with defineField and defineArrayField.
Scalar fields
import { defineField } from '@ekz/formix';
const refs = {
email: defineField(''),
age: defineField(0),
};
Pass initial values when editing existing entities:
defineField(entity?.email ?? '');
Binding with useField
const { value, setValue, error, touched, setTouched } = useField(field);
<input
value={value}
onChange={(e) => setValue(e.target.value)}
onBlur={() => setTouched(true)}
/>;
error is populated when a validator returns a message and the field is touched.
Array fields
Dynamic lists use defineArrayField and useArrayField:
import { defineArrayField, defineField } from '@ekz/formix';
import { List } from 'immutable';
function defineItemField(item?: Item) {
return {
label: defineField(item?.label ?? ''),
};
}
const items = defineArrayField(List<ItemFieldRefs>(), defineItemField);
const { items, push, remove, move } = useArrayField(field);
items.map((itemRef, index) => (
<ItemRow key={itemRef.id} field={itemRef} onRemove={() => remove(index)} />
));
Immutable collections
Formix works well with immutable.js Set, List, and Map as field values — especially for tags, ordered lists, and deduplication.
Field metadata
Field refs carry stable identities across renders. Use the same ref object for useField, useFieldValidation, and getValues.
Anti-patterns
- Raw
useStateper input — loses sharedvalid/modifiedand cross-field validation - String keys —
values.emailbreaks ref safety; useFieldRefinstead - Validation in save handlers — use
useFieldValidationso submit stays disabled until fixed