@aegatlin/form v0.0.4
Form State
Extremely simple, strongly typed, form state management in React.
This library is a thin (~20 lines) shell around React Flat Store.
You call buildFormState
and in return you get a Form
component that will keep track of your form state. You also get back two hooks. useForm
will return your current form state. useFormField
will return the name and value of a specific field, as well as a simple update function. That's it!
Table of Contents
There are 4 sections to this documentation.
- Reference: implementation details
- Explanation: conceptual intro to lib
- Tutorial: create a simple sign-in form
Explanation
Minimal Form State
A form is fundamentally simple. It is "just" a state machine containing fields, which are "just" name-value pairs.
Also, forms are one of the most complicated things to manage as a developer. Some examples of difficult form management tasks include: asynchronous field updates, multi-value selects, interdependent multi-field remote validations, etc. This library won't even try to do any of this. It will get out of your way while you try (and, yeah, good luck with that).
Other Libraries
Libraries like formik and react-hook-form are great. But, sometimes they are too much. They try to solve hard problems related to form management, and if you read enough of their documentation, and embrace enough of their paradigms, you can leverage their APIs to create good form experiences. But, if you are looking for something simpler, something that "just" manages form state, and let's you manage the rest, then this minimal form state library might be what you're looking for. It's so simple, in fact, that it's only around 50 lines of code. You can frankly just copy and paste the code into your codebase and move on. (Won't bother me none.)
I want a form library that just gives me easy access to form state and field state, and then gets out of my way. That's why I wrote this.
Tutorial
Sign In Form
Let's create a simple sign-in form with a email and a remember-me checkbox.
npm i @aegatlin/form
const initFormState = { email: '', rememberMe: false }
const { Form, useForm, useFormField } = buildFormState(initFormState)
function SignInForm() {
return (
<Form>
<Email />
<RememberMe />
<Submit />
</Form>
)
}
function Email() {
const { name, value, update } = useFormField('email')
return (
<input
type="text"
name={name}
value={value}
onChange={(e) => update(e.target.value)}
/>
)
}
function RememberMe() {
const { name, value, update } = useFormField('rememberMe')
return (
<input
type="checkbox"
name={name}
checked={value}
onChange={() => update(!value)}
/>
)
}
function Submit() {
const { email, rememberMe } = useForm()
const submit = () => {
console.log('submitting payload: ', JSON.stringify({ email, rememberMe }))
}
return <button onClick={submit}>Submit</button>
}
Reference
buildForm
- Input: initial form state.
- Output:
Form
,useForm
,useFormField
const { Form, useForm, useFormField } = buildForm({
a: 1,
b: '2',
c: { three: 3 },
})
Form
Form
is a React component that will wrap your Form. Internally, it creates a React Context within which it stores the form state.
There are no props.
function SomeForm() {
return <Form>...</Form>
}
useForm
useForm
is a React hook that returns form state.
- Inputs: none
- Outputs: form state
// assuming a form state of email and password...
function ChildComponent() {
const { email, password } = useForm()
// ...
}
useField
useField
is a React hook that returns field name and value fields, as well as an update function.
- Inputs: field name
- The field name is strongly typed, so typos or field names that are not present in the initial form state will throw type errors.
- Outputs:
name
: The field's name/key.value
: The field's value. The value is strongly typed.update
: The field's update function. The update function is strongly typed.
function ChildComponent() {
const { name, value, update } = useFormField('email')
// name => 'email'
// value => ''
update('test@example.com')
// value => 'test@example.com'
update(4) // type error!
// ...
}