← Back to list

Build a Reusable React Input Component with TypeScript

Learn how to build a scalable, reusable React input component using TypeScript, complete with error handling and prop forwarding.

Vetriselvan Panneerselvam · 2026-05-28 03:04 · 0 claps · 2.3 min read paywalled
#react #input-component #usestate #validation
Open on Medium ↗
Wiki topics: 🌐 · Web Development

H ey Devs 👋

When working with forms in React, one of the most common patterns is repeating the same input UI again and again: label, helper text, error message, focus state, disabled state, and so on. That repetition makes the code longer and harder to maintain.

To solve this, I created a reusable input component that keeps the form logic centralized and easy to use across the project.

Not a Medium member? You can read the full article for free by clicking here. 🔗

This is part 2 of creating reusable components in React. If you missed out on part 1. check it here

Step 1:

Creating a React functional component named InputField.tsx.

Step 2:

Creating a model that defines the input props to the InputField component. It should extend the standard HTML input attributes through InputHTMLAttributes<HTMLInputElement>. This means the input behaves like a normal HTML input, but with extra support for custom UI behavior.

export interface IInputFieldProps extends InputHTMLAttributes<HTMLInputElement> {
  label?: string;
  error?: string;
  info?: string;
}

Custom props for flexible usage

I added three custom props:

  • label?: string—displays a label above the input
  • error?: string—displays an error message below the input
  • info?: string—displays helper text below the input

Step 3:

export const InputField: React.FC<IInputFieldProps> = ({
  label,
  info,
  type = "text",
  id,
  name,
  value,
  onChange,
  onInput,
  onBlur,
  onFocus,
  disabled,
  readOnly,
  error,
  className,
  ...props
}) => {
  const [isfocused, setFocus] = useState<boolean>(false);

  const focused = (e: FocusEvent<HTMLInputElement, Element>) => {
    setFocus(true);
    onFocus?.(e);
  };

  const blurred = (e: FocusEvent<HTMLInputElement, Element>) => {
    setFocus(false);
    onBlur?.(e);
  };

  const inputClasses = [
    "base-input",
    className,
    error ? "input-error" : "",
    isfocused ? "input-focus" : "",
    disabled ? "input-disabled" : "",
    readOnly ? "input-readonly" : "",
  ]
    .filter(Boolean)
    .join(" ");

  return (
    <div className="input-field-wrapper">
      {label && <label htmlFor={id}>{label}</label>}
      <input
        {...props}
        type={type}
        name={name}
        disabled={disabled}
        readOnly={readOnly}
        id={id}
        value={value}
        onFocus={focused}
        onChange={onChange}
        onInput={onInput}
        onBlur={blurred}
        className={inputClasses}
      />
      {error ? (
        <small className="input-field-error">{error}</small>
      ) : (
        info && <small className="input-field-info">{info}</small>
      )}
    </div>
  );
};

The component accepts all normal input attributes through the props object. This is important because it allows the component to plug into existing React forms without needing a different API.

To handle the focus state. I also added a local focus state using:

const [focus, setFocus] = useState<boolean>(false);

This state keeps track of whether the user is currently interacting with the input.

Two handler functions are used for this:

  • focused() → sets the focus state to true and calls the passed onFocus
  • blurred() → sets the focus state to false and calls the passed onBlur

This gives the input more interactivity and makes it possible to style based on focus.

Now the reusable component is ready, and you can wrap it with a form. There are some concepts like using the forwardRef; also, we can achieve it. Let me know if anyone wants to explore that.

Want to explore more concepts? Share your thoughts and what component we can take next in the response.

Check out the full working example on GitHub: 👉 Source Code: react-toast

Thanks for reading! If this was helpful, consider clapping 👏 and following for more full-stack tips. Do you have questions or suggestions? Drop them in the response below!

✍️ Author: **Vetriselvan Panneerselvam**

👨‍💻 Full Stack Developer | 💡 Code Enthusiast | 📚 Lifelong Learner | ✍️ Tech Blogger | 🌍 Freelance Developer


메타데이터
post_id
2f885b7bbf5a
slug
build-a-reusable-react-input-component-with-typescript-2f885b7bbf5a
url
https://medium.com/@vetriselvan_11/build-a-reusable-react-input-component-with-typescript-2f885b7bbf5a
canonical_url
https://medium.com/@vetriselvan_11/build-a-reusable-react-input-component-with-typescript-2f885b7bbf5a
author_url
https://medium.com/@vetriselvan_11
status
ok
fetched_at
2026-06-09 15:37:30