JAVASCRIPT

Create a Custom Hook for Form Input Management

Learn to build a reusable custom React hook for handling form input state, validation, and change events, simplifying form development.

import React, { useState } from 'react';

// Custom Hook for input management
function useInput(initialValue, validator) {
  const [value, setValue] = useState(initialValue);
  const [error, setError] = useState(null);

  const handleChange = (event) => {
    const newValue = event.target.value;
    setValue(newValue);

    if (validator) {
      const validationError = validator(newValue);
      setError(validationError);
    }
  };

  const reset = () => {
    setValue(initialValue);
    setError(null);
  };

  return {
    value,
    error,
    handleChange,
    reset,
    bind: {
      value,
      onChange: handleChange,
    },
  };
}

function MyForm() {
  const nameValidator = (name) => (name.length < 3 ? 'Name must be at least 3 characters' : null);
  const emailValidator = (email) => (!email.includes('@') ? 'Invalid email format' : null);

  const nameInput = useInput('', nameValidator);
  const emailInput = useInput('', emailValidator);

  const handleSubmit = (event) => {
    event.preventDefault();
    if (!nameInput.error && !emailInput.error && nameInput.value && emailInput.value) {
      alert(`Submitted: Name - ${nameInput.value}, Email - ${emailInput.value}`);
      nameInput.reset();
      emailInput.reset();
    } else {
      alert('Please fix the errors in the form.');
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>Name:</label>
        <input type="text" {...nameInput.bind} />
        {nameInput.error && <p style={{ color: 'red' }}>{nameInput.error}</p>}
      </div>
      <div>
        <label>Email:</label>
        <input type="email" {...emailInput.bind} />
        {emailInput.error && <p style={{ color: 'red' }}>{emailInput.error}</p>}
      </div>
      <button type="submit">Submit</button>
    </form>
  );
}

export default MyForm;
How it works: This custom hook, `useInput`, encapsulates the logic for managing a single form input's state, its change handler, and basic validation. It takes an `initialValue` and an optional `validator` function. It returns the current `value`, any `error` message, a `handleChange` function, a `reset` function, and a `bind` object (which conveniently provides `value` and `onChange` props for direct spreading onto an `<input />` element). This allows for cleaner, more reusable form input management across multiple components.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs