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 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
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
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
<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
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
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
Learn more about Validation here
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
:
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
Input
can be validated completely manually using the validate
prop. As a companion, there is also a useValidatorChain
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
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
React Binden also supports Textarea, Select, Checkboxes & 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
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
Have any ideas to improve react-binden? Why not Discuss?
Follow us on twitter/@krtirtho
Give a 🌟 on Github