GitHub

Tired of writing custom form validation on every project you might work on? Let’s try hocForm, form validation on React has rarely been so simple! πŸ€—

Requirements

hocForm needs at least react@16.3.1 and react-dom@16.3.1 to work.

Installation

Using npm:

npm install --save hoc-form

yarn add hoc-form works fine too!

Usage

import React from 'react';
import hocForm, { Field } from 'hoc-form';
// First, we need a input component to render our text field
function Input({
  input = {},
  label = '',
  meta = {},
  placeholder = '',
  type = 'text',
}) {
  return (
    <div>
      <label>
        {label}
      </label>
      <input
        placeholder={placeholder}
        type={type}
        {...input}
        onBlur={e => input.onBlur && input.onBlur(e.target.value)}
        onChange={e => input.onChange(e.target.value)}
      />
      {meta.error && <span>{meta.error}</span>}
    </div>
  );
}
// Then, we need to create our form component and its helpers
const unavailableUsernames = [
  'elonmusk',
  'ironman',
  'lukeskywalker',
];
function validateLogin(value = '') {
  if (value.trim() === '') {
    return Promise.reject('Please enter an username');
  }
  return unavailableUsernames.includes(value)
    ? Promise.reject('This username is unavailable')
    : Promise.resolve()
}
function validatePassword(value = '') {
  if (value.trim().length < 6) {
    return Promise.reject('Password must contain 6 characters or more');
  }
  return Promise.resolve();
}
function Form({ onSubmit }) {
  return (
    <form onSubmit={onSubmit} noValidate>
      <Field
        name="login"
        component={Input}
        props={{
          label: 'Login *',
          onBlur: value => validateLogin(value),
          placeholder: 'elonmusk',
          type: 'string',
        }}
      />
      <Field
        name="pwd"
        component={Input}
        props={{
          label: 'Password *',
          type: 'password',
        }}
      />
      <button type="submit">Sign up</button>
    </form>
  );
}
// Finally, an export of our wrapped form component
// with a validation function
export default hocForm({
  validate(values, props) {
    let errors = {};
    const errorCatcher = (key, callback, ...args) => (
      callback(values[key], args)
        .catch(error => ({ [key]: error }))
    );
    return Promise.all([
      errorCatcher('login', validateLogin),
      errorCatcher('pwd', validatePassword),
    ]).then((errors) => {
      const results = errors.reduce((acc, item) => ({ ...acc, ...item }), {});
      return Object.keys(results).length ? Promise.reject(results) : Promise.resolve();
    });
  }
})(Form);

Please check out the complete demo! πŸš€

API

hocForm({ options })(MyFormComponent) => React.Component

Renders your MyFormComponent contexted with hocForm.

Two arguments are required:

  • An options object to define the validate function and optional initialValues
  • A form React.Component to render.

options.validate(values, props) => Promise

Validates the form on submit.

Arguments:

  1. values (Object): An object containing all fields keys and their value.
  2. props (Object): An object containing all props provided to MyFormComponent.

Returns:

  • A promise:
    • On success, your must return Promise.resolve()
    • In case of failure, your must return Promise.reject({}). The object parameter must contain every field key with its error (type of string or else, depends on how your components used with Field are designed).

Example, with errors as strings:

function validate(values, props) {
  let errors = {};
  if (values.username) {
    if (!props.isUsernameAvailable(values.username)) {
      errors = { ...errors, username: 'This username is unavailable' };
    }
  } else {
    errors = { ...errors, username: 'Please enter an username' };
  }
  if (!values.password) {
    errors = { ...errors, password: 'Please enter a password' };
  }
  return Object.keys(errors).length
    ? Promise.reject(errors)
    : Promise.resolve();
}

options.initialValues: Object

Object containing all initial values following fields keys.

Example:

initialValues: {
  country: 'United Kingdom',
  phone: '+44',
}

MyFormComponent: React.Component

A React.Component rendering a form including some hocForm.Field items.

Example:

"function Form({ onSubmit }) { return (

Read the original on github.com β†—