usetheform
v4.0.0
Published
React library for composing declarative forms in React and managing their state.
Downloads
1,216
Maintainers
Readme
💡 What is Usetheform?
Usetheform is a lightweight, dependency-free React library for composing declarative forms and managing their state. It's simple to use, flexible, and powerful for handling nested fields, validation, and much more.
📚 Documentation ⚡ Quickstart 🔥 Features 📖 Recipes 🧠 Motivation 🧪 Code Sandboxes 🤝 How to Contribute 📄 License
:fire: Features
- 📦 Easy integration with libraries like React Select/Material UI and React Dropzone/Material UI Dropzone
- ✅ Sync and Async validation at:
- 🔍 Schema validation with:
- 🧬 Follows native HTML standards — see in action
- 🧠 Reducer support at:
- 🧩 Easy handling of arrays, objects, and nested structures
- 📦 Tiny bundle size, zero dependencies — Check it on Bundlephobia
:zap: Quickstart
Install usetheform using your preferred package manager:
npm install --save usetheformyarn add usetheformBasic usage example:
import React from "react";
import { Form, Input, useValidation } from "usetheform";
import { ReducerFn, ValidatorFn, OnChangeFormFn, OnSubmitFormFn } from "usetheform/types";
interface MyFormState {
firstname: string;
lastname: string;
age: number;
}
const preventNegativeNumber: ReducerFn<MyFormState["age"]> = (next) =>
next <= 0 ? 0 : next;
const required: ValidatorFn<MyFormState["firstname"]> = (value) =>
value?.trim() ? undefined : "Required";
export default function App() {
const onChange: OnChangeFormFn<MyFormState> = (formState) => console.log("ON_CHANGE:", formState);
const onSubmit: OnSubmitFormFn<MyFormState> = (formState) => console.log("ON_SUBMIT:", formState);
const [status, validation] = useValidation([required]);
return (
<Form<MyFormState> onSubmit={onSubmit} onChange={onChange}>
<Input name="firstname" type="text" touched {...validation} />
{status.error && <span>{status.error}</span>}
<Input name="lastname" type="text" />
<Input name="age" type="number" value={18} reducers={preventNegativeNumber} />
<button type="submit">Submit</button>
</Form>
);
}:book: Recipes
Accessing form fields outside the Form context
🧱 Step 1: Create a form store
interface FormState { counter: number; }import { createFormStore } from 'usetheform';
const [formStore, useFormSelector] = createFormStore<FormState>({ counter: 0 });
export const awesomeFormStore = formStore;
export const useAwesomeFormSelector = useFormSelector;🧩 Step 2: Create your awesome form
import { Form, Input } from 'usetheform';
import { awesomeFormStore } from './awesomeFormStore';
export default function AwesomeForm() {
return (
<>
<Form<FormState> formStore={awesomeFormStore}>
<Input type="number" name="counter" value="0" placeholder="Counter" />
</Form>
<Counter />
</>
);
}🔌 Step 3: Connect your components
import { useAwesomeFormSelector } from './awesomeFormStore';
export const Counter = () => {
const [counter, setCounterValue] = useAwesomeFormSelector<"counter">((state) => state.counter);
return (
<div>
<span>{counter}</span>
<button onClick={() => setCounterValue(prev => ++prev)}>Increase</button>
<button onClick={() => setCounterValue(prev => --prev)}>Decrease</button>
<button onClick={() => setCounterValue(0)}>Reset</button>
</div>
);
};:brain: Motivation
Usetheform was created to provide a highly flexible, declarative way to handle forms in React with no dependencies. It supports:
- Nested field structures
- Synchronous & asynchronous validation
- Custom input and reducer logic
- Schema-based validation
- Tiny footprint
If you find this library useful, please ⭐ the repo. It means a lot! 🙏
👤 Author
- Antonio Pangallo — @antonio_pangall
⭐ Stargazers
Code Sandboxes
- Twitter-style Form Bar
- Shopping Cart
- Form Examples (Select, Slider, Collections)
- Various Implementations
- Wizard
- FormContext
- Material UI + React Select
- Validation (Yup, Zod, Joi, Superstruct)
- React Dropzone + Material UI
How to Contribute
🎉 Thanks for considering contributing! Please read our CONTRIBUTING.md for guidelines.
📄 License
This project is licensed under the MIT License. See the LICENSE file for details.
