
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
react-easy-form-hook
Advanced tools
A headless hook for creating forms in react. Created to be fast, configurable and easy to use.
Let's create a simplest possible form with user data, address and start date
import React, { useMemo } from 'react';
import { FieldFactory, useForm, FieldSettings, FieldType } from 'easy-react-form-hook';
export function SimpleForm() {
const fields = useMemo(() => [
{ type: FieldType.Text, accessor: "firstName", label: "First Name", },
{ type: FieldType.Text, accessor: "lastName", label: "Last Name", },
{ type: FieldType.Text, accessor: "city", label: "City", },
{ type: FieldType.Text, accessor: "street", label: "Street", },
{ type: FieldType.Date, accessor: "startDate", label: "startDate", },
] as FieldSettings[], []);
const form = useForm({ fieldsSettings: fields });
const submit = (object: any) => {/** you api call here */}
return <>
{form.fields.map(field => <div key={field.accessor}><FieldFactory {...field} /></div>)}
<button disabled={ (!form.formState.valid && !form.formState.changed)} onClick={() => submit(form.object)}>Submit</button>
</>;
}
FieldFactory, will handle creation of all field types in following format
<label {...field.labelAttributes}>{field.label}</label>
<input {...field.attributes} />
or
<label {...field.labelAttributes}>{field.label}</label>
<select {...field.attributes}>
{field.options?.map(option => <option key={option.value} {...option} />)}
</select>
You can always implement your own factory
Same as above, just change accessors and it is done.
import React, { useMemo } from 'react';
import { FieldFactory, useForm, FieldSettings, FieldType } from 'easy-react-form-hook';
export function SimpleForm() {
const fields = useMemo(() => [
{ type: FieldType.Text, accessor: "user.firstName", label: "First Name", },
{ type: FieldType.Text, accessor: "user.lastName", label: "Last Name", },
{ type: FieldType.Text, accessor: "address.city", label: "City", },
{ type: FieldType.Text, accessor: "address.street", label: "Street", },
{ type: FieldType.Date, accessor: "startDate", label: "startDate", },
] as FieldSettings[], []);
const form = useForm({ fieldsSettings: fields });
const submit = (object: any) => {/** you api call here */};
return <>
{form.fields.map(field => <div key={field.accessor}><FieldFactory {...field} /></div>)}
<button disabled={ (!form.formState.valid && !form.formState.changed)} onClick={() => submit(form.object)}>Submit</button>
</>;
}
Field is validated using RegExp everytime if regex property is provided and onChange event is called./
RegExp is also provided to field as attribute pattern so it is calculated by browser as well. This allows to use css with selector such as input:valid or input:invalid.
Also <input type='submit'> can laverage this validation as well.
Based on previous example, let's change input user.fistName and add regex.
{ type: FieldType.Text, accessor: "firstName", label: "First Name", regex: /[a-zA-Z]{2,15}/, },
If any of the fields in the form are not valid or not populated when required, state of the form is set to invalid form.formState.valid = false.
import { useForm } from 'east-react-from-hook'
const form = useForm(settings)
export interface FormSettings<TObject, TCustomProps> {
fieldsSettings: FieldSettings<TCustomProps>[];
defaultSettings?: DefaultFieldSettings<TCustomProps>;
initialState?: TObject;
disabled?: boolean;
keepEmptyProperties?: boolean;
refreshObjectOnChange?: boolean;
formName?: string;
}
fieldSettings
const fields =[
{ type: FieldType.Text, accessor: "name", label: "Name", },
{ type: FieldType.TextArea, accessor: "comment", label: "Comment",},
]
defaultSettings
initialState
{}disabled
keepEmptyProperties
{}
If user have only populated field name with value John Smith, then form object will look as below {
name: "John Smith"
}
If both fields were populated, then form object will have both properties
{
name: "John Smith",
comment: "This is a new user",
}
refreshObjectOnChange
false. To create a form object on demand, use function getObject: () => TObject; from IForm interface returned by useForm hook.formName
formDepending on the field type selected, there will be different options and field attribute to set. However, all fields have following properties in common
type: FieldType;
accessor: string;
disabled?: boolean;
label: string;
tag?:string;
type: FieldType
enum FieldType {
Checkbox = "checkbox",
Color = "color",
Date = "date",
DateRange = "dateRange",
Email = "email",
File = "file",
Month = "month",
Number = "number",
NumericRange = "numberRange",
Range = "range",
Radio = "radio",
Passowrd = "password",
Search = "search",
Select = "select",
SelectMultiple = "multiselect",
Submit = "submit",
Telephone = "tel",
Text = "text",
TextArea = "textarea",
Time = "time",
Week = "week",
}
accessor
{
user: {
firstName: "John",
lastName: "Smith",
address: {
street: "Main St."
city: "New Town"
}
},
comment: "This is a new user",
}
we have following accessors
user.firstName
user.lastName
user.address.street
user.address.city
comment\
disabled
label
<label>label value goes here</label>tag
Object used to provide properties and field attributes that will be merged with all fields. If specific field settings provide the same attributes, they will override default settings.
className?: string;
classNameLabel?: string;
customProps?: TCustomProps;
type?: FieldType;
Objet returned by hook useForm
fields: FormField<TCustomProps>[];
formState: IFormState;
object: TObject;
getObject: () => TObject;
Object created from all the fields.
Function used to get final object when a `refreshObjectOnChange` is set to false.
List of fields to be rendered. There are multiple type of fields with following attributes in common.
accessor: string;
accessors: string[];
customProps?: TCustomProps;
disabled?: boolean;
initialValue?: string | number;
labelAttributes?: FormFieldLabel;
tag?:string;
value?: any;
accessor
accessors
customProps
disabled
initialValue
initialState in FormSettings. It is used to decide if form field and consequently whole from has been change. See formState: IFormState changed.labelAttributes
<label> tag. Consists of following attributesid?: string
className?: string,
htmlFor?: string,
tag
value
Object used to keep various information about the Form
/** Defines if all fields with validation are valid */
valid: boolean;
/** Has form changed from inital value */
changed: boolean;
/** If true, properties that are undefined will set to null, otherwise thwy will not be created in final Object */
keepEmptyProperties?: boolean;
/** Is form dissabled */
disabled?: boolean;
/** If true, final object will be recreated every time onChange event is called on any input */
refreshObjectOnChange?: boolean;
FAQs
A headless hook for creating forms in react. Created to be fast, configurable and easy to use.
We found that react-easy-form-hook demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.