MobX library for non-intrusive class-based model enhancement. Acting as a sentinel, it provides change detection, reactive validation, and form integration capabilities without contamination.
npm install @mobx-sentinel/reactUtility hooks and standard bindings for React applications using @mobx-sentinel/form.
Automatically resets the form when the component mounts and unmounts. This is useful for cleaning up form state when navigating between pages or showing/hiding form components.
``tsx
import { observer } from "mobx-react-lite";
import { useFormAutoReset } from "@mobx-sentinel/react";
const MyFormComponent = observer(({ model }) => {
const form = Form.get(model);
// Auto-resets form on mount/unmount
useFormAutoReset(form);
return
$3
Adds a lifecycle handler to the form with automatic cleanup. The handler is automatically removed when the component unmounts. No need to memoize the handler - it's stored in a ref internally and always uses the latest version.
It's just a wrapper for
form.addHandler().`tsx
import { observer } from "mobx-react-lite";
import { useFormHandler } from "@mobx-sentinel/react";const MyFormComponent = observer(({ model, onSuccess }) => {
const form = Form.get(model);
// No need to memoize - the hook handles it
useFormHandler(form, "submit", async () => {
await saveToAPI(model);
return true; // Return true to indicate success
});
useFormHandler(form, "didSubmit", () => {
onSuccess(); // This always uses the latest onSuccess callback
});
return
{/ your form fields /};
});
`Standard Form Bindings
These pre-built bindings are designed for native HTML form elements (
, Multiple selection:
`tsx
{...form.bindSelectBox("tags", {
multiple: true,
getter: () => model.tags.map((t) => t.id),
setter: (codes) => (model.tags = codes.map(findTag)),
})}
>
{availableTags.map((tag) => (
))}
`$3
Binds submit buttons with automatic state management. The button is automatically disabled when the form is invalid, submitting, or validating.
`tsx
// Shows errors on hover
// With custom click handler
{...form.bindSubmitButton({
onClick: (e) => console.log("Submit clicked"),
})}
>
Submit
`ARIA attributes set:
-
aria-busy: true when submitting or validating
- aria-invalid: true when form is invalid
- disabled: true when form cannot be submitted$3
Binds label elements to form fields with error state display. Can associate with single or multiple fields.
`tsx
// Single field
// Multiple fields (shows first error)
// Custom htmlFor
`$3
All bindings support extending the default event handlers:
`tsx
{...form.bindInput("email", {
getter: () => model.email,
setter: (v) => (model.email = v),
onChange: (e) => console.log("Changed:", e.currentTarget.value),
onFocus: (e) => console.log("Focused"),
onBlur: (e) => console.log("Blurred"),
})}
/> type="checkbox"
{...form.bindCheckBox("terms", {
getter: () => model.terms,
setter: (v) => (model.terms = v),
onChange: (e) => console.log("Checked:", e.currentTarget.checked),
})}
/>
`$3
By default, bindings use auto-generated field IDs. You can override them:
`tsx
{...form.bindInput("username", {
id: "custom-username-input",
getter: () => model.username,
setter: (v) => (model.username = v),
})}
/>
`$3
All bindings automatically set ARIA attributes for accessibility:
`tsx
const MyForm = observer(({ model }) => {
const form = Form.get(model); return (
... / })} />
{/ Binding sets aria-invalid and aria-errormessage automatically /} {/ Optionally display errors manually /}
{form.field("email").isErrorReported && (
{Array.from(form.field("email").errors).join(", ")}
)}
);
});
``