React Forms Made Easy with react-binden🚀
Tags: javascript, react, webdev, tutorial
Published: 2021-10-31 09:10:25

Introducing **React Binden** 🎉🚀

A react form handling library which is actually easy

React Binden is inspired from Vue's `v-bind` directive & is extremely lightweight yet fast

Its,

- Lightweight, Fast & Tree-shakable
- has Out of the Box **validation** without any 3rd party library
- optimizes both **Hooks & Components** to get the best of both worlds
- offers custom curated collection of useful **Regex** for validation purposes
- UI component library **proof**
- can be integrated with any UI component library/framework **without any 3rd party library**
- **zero** dependencies

## Why created this?

React forms, no doubt can be a nightmare for any developer. It can be messy to create a simple Login form in React

One day, while using Vuejs for creating a [medium.com](http://medium.com) clone, I encountered with Vue's `v-bind` directive. Which allows to bind a value of a field with a variable. In React, that's not possible as React supports only one-way data-binding. Just think, if it was available in React, it'd been a god sent gift but alas!. Don't be sad as we can mimic two-way data-binding in React with *state-up-lifting*. It means declaring the state of a child in the parent & then passing that down to child. Kind of like prop-drilling but in a managed manner. You shouldn't do more than 2 times of state-up-lifting as it'd make the UI slow leading to huge re-renders

So I experimentally tried mimicking `v-bind` for `input` & walla, it worked fine. I though it might cause performance issues & huge re-renders but surprisingly it didn't instead it's fast & fast as normal. Then, I decided finish writing the library

Another reason is simplicity. I found every form library having some kind of complexity even though, they were doing their best to simplify React Form handling experience. Custom schema for validation, spreading props in Fields, hooks that returns huge amount of objects which you've to manually handle etc. kind of made me really confused. I discovered that, every form library is either completely hook based or completely component render function based or provides both API. I never found a single one that utilizes both custom components & hooks together. So, in with React-Binden I tried closing that gap which will give the developer best of both world

Third & final reason is size. Current form libraries aren't lightweight except react-final-form. So making a decent form library which is lightweight and tree-shakable was React Binden's one of the main goals. BTW, it uses ESNext module system

## How to use

React Binden is extremely easy to use. It has the simplest API for handling React Forms. It provides hooks & custom components

The most important ones are the `useModel`, `Form` & `Input`. Using these 3, you can complete most of the job. Now let's see how to use `useModel`

### Using useModel

`useModel` is nothing but a simple hook that just declares some required states for a `Input`'s model. It requires a *default value* which can be a number, string or an Array (applicable only for checkbox-group)*.* And has an optional parameter that can be used pass all the validation prop of an `Input`

```jsx
import { useModel } from 'react-binden';

/*---------------------------------------*/

const model = useModel('', {
        name: 'some-field',
        max: 20,
        min: [5, 'minimum 5'],
        maxLength: 20,
        minLength: 5,
        pattern: regex.email,
        required: true,
        validate: (_value, _touched) => true,
        'semantic-validation': true,
});

// all the states/properties
model.value;
model.error;
model.touched;
model.default;
model.validations;

// all the methods
model.setValue('Some value');
model.setError('Some Error');
model.setTouched(true);
```

> Learn more about `useModel` [**here**](https://react-binden.netlify.app/docs/hooks/use-model)
> 

### Using Form

`Form` is a typical form component as well as a context provider. It doesn't hold a huge amount of state for the field. Only keeps the state of submit, reset & if all field have don't have any error

You can use `onSubmit` prop to handle form submission just like a vanilla HTML form. And it supports all other form attributes

Example of a `Form`

```jsx
<Form
    onSubmit={async (event, {reset, errors}, methods) => {
        try{
        // handling form submission
        }
        catch(e){
        // handle exceptions
        }
    }}
>
    {/*... other components*/}
</Form>
```

> More about `Form` can be found [**here**](https://react-binden.netlify.app/docs/components/form)
> 

### Using Input

`Input`  is what acts like an input field. `useModel`'s model have to be bind with this component's `model` prop. It takes all the validation props. Since React Binden follows HTML validation standards & semantic HTML form validation attributes, all the HTML input validation props is present. But instead of validating while submission, React Binden validates in real time. You can pass custom error message with those validation props

Validation props that are supported

- `min`, `max` (for numeric values)
- `minLength`, `maxLength` (for string values)
- `pattern` (through regex)
- `required`

```jsx
export function Example() {
    const user = useModel('');

    return (
        <Input
            model={user}
            maxLength={30}
            // passing a custom error msg using Tuples
            minLength={[5, 'Minimum 5 characters']}
            required
        />
    );
}
```

> Here's more about **[Input](https://react-binden.netlify.app/docs/components/input)**
> 

> Learn more about Validation [**here**](https://react-binden.netlify.app/docs/tutorials/validation/)
> 

Validating password & confirm password is a pain, right? This is where `imprint-model` comes handy. Pass the password model to this & the field will only match to that password field

Example of `imprint-model`:

```jsx
const password = useModel('');
const confirmPassword = useModel('');

return (
    <Form onSubmit={handleSubmit}>
        <Input
            model={password}
            required
            pattern={regex.moderatePassword}
            placeholder="Password"
        />
        <Input
            model={confirmPassword}
            // passing the model that should be imprinted/followed
            imprint-model={password}
            required
            placeholder="Confirm Password"
        />

        <button type="submit">Sign Up</button>
    </Form>
);
```

> Might be thinking about **integrating React Binden with an UI component library/framework**. No worries. You can learn about it [**here**](https://react-binden.netlify.app/docs/tutorials/3rd-party-ui-libraries)
> 

`Input` can be validated completely manually using the `validate` prop. As a companion, there is also a **[`useValidatorChain`](https://react-binden.netlify.app/docs/hooks/use-validator-chain)** hook which can be used for using multiple validation functions at once

### Regex

React Binden also provides an useful list of Regular Expressions that can be used with `Input`'s `pattern` prop. Suppose validating an email field. This can be done with `regex`

```jsx
import { regex, useModel, Input } from 'react-binden';

export function Login() {
    const email = useModel('');

    return (
        {/*....Form & other component....*/}
        <Input
            type="email"
            model={email}
            // using `regex.email` for validating email
            pattern={[regex.email, 'Should be a valid email']}
            required
        />
        {/*....Form & other component....*/}
    );
}
```

> The list of available Regex can be found [**here**](https://react-binden.netlify.app/docs/regex)
> 

React Binden also supports [**Textarea**](https://react-binden.netlify.app/docs/components/textarea), **[Select](https://react-binden.netlify.app/docs/components/select), [Checkboxes](https://react-binden.netlify.app/docs/examples/checkboxes) & [Radio Group](https://react-binden.netlify.app/docs/examples/radio-group).** And the entire library is written with Typescript❤️ so don't worry about Typescript support

## Conclusion

This is a short review & tutorial of React Binden. The full documentation is what you should be looking for. To learn about all the features of React Binden visit [react-binden.netlify.app](https://react-binden.netlify.app/)

React Binden is a completely new library & heavily inspired by other form libraries too. Those are an asset & Thanks❤️ to those library authors for their outstanding generosity for the OSS community

If you ever encounter any bug related to React  Binden [create an issue on Github](https://github.com/KRTirtho/react-binden/issues/new?assignees=&labels=&template=bug_report.md&title=%3CSomething%3E+doesn%27t+work)

Have any ideas to improve react-binden? Why not [Discuss](https://github.com/KRTirtho/react-binden/discussions/new)?

Follow us on [twitter/@krtirtho](https://twitter.com/KrTirtho)

Give a 🌟 on [Github](https://github.com/KRTirtho/react-binden)