0.0.4 • Published 2 years ago

@aegatlin/form v0.0.4

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

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!

  // ...
}