Skip to content

Solid.js Forms — Building Reactive Forms

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Solid.js Forms. We cover key concepts, practical examples, and best practices to help you master this topic.

Learn Solid.js forms: handle form state with signals, validate input, manage submissions, and build complex form components with reactive patterns.

In this lesson, you'll build forms using signals for state management, handle validation, and manage form submissions.

What You'll Learn

How to manage form state with signals, validate input with reactive patterns, handle form submission, and build reusable form inputs.

Why It Matters

Forms are the primary way users input data. Solid.js signals make form state management straightforward and efficient.

Real-World Use

Doda Browser's settings page uses reactive forms where changes update the preview immediately without submission.

flowchart LR
    A[Input] --> B[Signal]
    B --> C[Validation]
    C --> D[Display/Submit]
    style B fill:#2c4f7c,color:#fff

Basic Form

function ContactForm() {
  const [name, setName] = createSignal("");
  const [email, setEmail] = createSignal("");

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log({ name: name(), email: email() });
  };

  return (
    <form onSubmit={handleSubmit}>
      <input value={name()} onInput={(e) => setName(e.target.value)} />
      <input value={email()} onInput={(e) => setEmail(e.target.value)} />
      <button type="submit">Submit</button>
    </form>
  );
}

Form Validation

function ValidatedForm() {
  const [email, setEmail] = createSignal("");
  const [submitted, setSubmitted] = createSignal(false);

  const emailError = createMemo(() => {
    if (!email()) return "Email is required";
    if (!email().includes("@")) return "Invalid email format";
    return null;
  });

  const handleSubmit = (e) => {
    e.preventDefault();
    setSubmitted(true);
    if (!emailError()) {
      console.log("Valid:", email());
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input value={email()} onInput={(e) => setEmail(e.target.value)} />
      {submitted() && emailError() && <p>{emailError()}</p>}
      <button type="submit">Submit</button>
    </form>
  );
}

Reusable Input Component

function FormField({ label, value, onInput, error, type = "text" }) {
  return (
    <div>
      <label>{label}</label>
      <input type={type} value={value()} onInput={onInput} />
      {error && <p>{error}</p>}
    </div>
  );
}

Common Mistakes

  1. Not using onInput for real-time updates: onChange fires on blur. Use onInput for immediate updates as the user types.
  2. Mutating signal values directly: name = newValue doesn't trigger updates. Always use the setter: setName(newValue).
  3. Not preventing default form submission: Without e.preventDefault(), the form reloads the page.
  4. Validating only on submit: Validate reactively with memos for real-time feedback.
  5. Not resetting form after submission: After successful submit, reset signals to their initial values.

Practice Questions

  1. How do you bind an input value to a signal? Answer: Set value={signal()} and onInput={(e) => setSignal(e.target.value)}.

  2. What is the difference between onInput and onChange? Answer: onInput fires on every keystroke. onChange fires when the input loses focus (blur).

  3. How do you prevent form page reload? Answer: Call e.preventDefault() in the submit handler.

  4. How do you validate form fields reactively? Answer: Use createMemo that reads the field signal and returns an error message or null.

Challenge

Build a registration form with validation for: username (min 3 chars), email (valid format), password (min 8 chars, must contain number), and confirm password (must match). Show errors only after first submission attempt.

Mini Project

Create a multi-field survey form with live preview. As users fill in fields, a preview panel updates in real-time showing the formatted results.

FAQ

How do I handle form reset?

: Set all signals to their initial values after successful submission.

Can I use uncontrolled inputs?

: Solid.js prefers controlled inputs with signals. Uncontrolled inputs work but don't integrate with reactivity.

How do I handle textarea and select?

: Same pattern: value={signal()} + onInput={handler} for textarea. value={signal()} + onChange={handler} for select.

What about form libraries?

: Solid.js works with form validation libraries. Create custom hooks for complex validation logic.

What's Next

Learn about Solid.js Context for sharing state across the component tree.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro