Skip to content

React Form API Reference

The @resourge/react-form package provides a type-safe, minimal-re-render, and flexible API to build complex forms in React.


Manages form state, validation, and submission.

import { useForm } from "@resourge/react-form";
const { form, field, handleSubmit, getErrors } = useForm({ email: "" });
const onSubmit = handleSubmit((data) => console.log(data));
return (
<form onSubmit={onSubmit}>
<input {...field("email")} placeholder="Email" />
<span>{getErrors("email")[0]}</span>
<button type="submit">Submit</button>
</form>
);
  • initialState: Object, function, or class representing initial form data.

  • options (optional):

    • onChange: Called on any field change.
    • onSubmit: Called when form is valid and submitted.
    • validate: Returns validation errors.
    • watch: Reacts to specific field changes.
    • validationType: "onSubmit" | "onTouch" | "always"
Method / PropertyDescription
formReactive state object. You can mutate it directly.
field(key, options?)Binds form state to an input field.
handleSubmit()Validates and submits the form.
hasError(key)Returns true if field has an error.
getErrors(key)Returns error messages for a field.
changeValue(key, val)Set field value manually.
getValue(key)Gets a specific value.
hasTouch(key)Checks if field was touched.
isTouchedChecks if any field was touched.
isValidTrue if all fields pass validation.
reset()Resets the form.
resetTouch()Resets touch state.
setError()Manually sets errors.
updateController()Forces a Controller re-render.
contextRequired for context providers.
errorsThe full error object.

Used for deeply nested or segmented forms. When you have a form with multiple sections or nested fields, useFormSplitter allows you to manage each section independently while still being part of the same form context.

This is particularly useful for large forms where you want to break down the form into smaller, manageable parts without losing the overall form state.

Example form class structure:

class User {
public profile: {
firstName: string;
lastName: string;
};
public address: {
street: string;
city: string;
};
}

On the main form, you can use useForm to manage the entire user profile:

import { useForm, FormProvider } from "@resourge/react-form";
const { context } = useForm(new User());
return (
<FormProvider context={context}>´
<ProfileSection />
<AddressSection />
</FormProvider>
);

Then, in a sub-form for the ProfileSection component, you can use useFormSplitter to manage just the profile fields:

const { field, form } = useFormSplitter("profile");
return (
<>
<input {...field("firstName")} />
<input {...field("lastName")} />
</>
);
  • formFieldKey: Field name that acts as root of the sub-form.

Same as useForm, but with storage persistence.

This hook allows you to save form state to localStorage or sessionStorage, making it easy to restore form data across sessions or page reloads.

const { form, restoreFromStorage } = useFormStorage(
{ email: "" },
{
uniqueId: "login-form",
storage: localStorage,
version: "v1",
}
);
OptionDescription
uniqueIdStorage key identifier
storagelocalStorage, sessionStorage, or custom
autoSyncWithStorageDefaults to true
shouldClearAfterSubmitClear on submit (true by default)
onLoading, onStorageErrorLifecycle callbacks
versionClear cache if version mismatches
@PreserveClass
class User {
email = "";
name = "";
}

Or:

We recommend registering classes to ensure proper serialization on the root of the application index.js or App.tsx.

import { registerClass } from "@resourge/react-form";
import User from "./models/User";
registerClass(User);

Provides context for child components.

import { FormProvider } from "@resourge/react-form";
import { useForm } from "@resourge/react-form";
const { context } = useForm({ username: "", password: "" });
<FormProvider context={context}>
<MyFormFields />
</FormProvider>

Hook to access context provided by Form or FormProvider.

const context = useFormContext<FormData>();

Component wrapper for controlled fields to avoid unnecessary renders.

import { Controller } from "@resourge/react-form";
const { context, field } = useFormContext<FormData>();
<Controller name="username" context={context}>
<input {...field("username")} />
</Controller>

import { useForm } from "@resourge/react-form";
const { form, field, handleSubmit, getErrors } = useForm({
username: "",
password: "",
});
const onSubmit = handleSubmit((data) => {
console.log("Submitted:", data);
});
return (
<form onSubmit={onSubmit}>
<input {...field("username")} />
<input {...field("password")} type="password" />
<button type="submit">Login</button>
</form>
);