Solid.js Forms — Building Reactive Forms
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
- Not using
onInputfor real-time updates:onChangefires on blur. UseonInputfor immediate updates as the user types. - Mutating signal values directly:
name = newValuedoesn't trigger updates. Always use the setter:setName(newValue). - Not preventing default form submission: Without
e.preventDefault(), the form reloads the page. - Validating only on submit: Validate reactively with memos for real-time feedback.
- Not resetting form after submission: After successful submit, reset signals to their initial values.
Practice Questions
How do you bind an input value to a signal? Answer: Set
value={signal()}andonInput={(e) => setSignal(e.target.value)}.What is the difference between
onInputandonChange? Answer:onInputfires on every keystroke.onChangefires when the input loses focus (blur).How do you prevent form page reload? Answer: Call
e.preventDefault()in the submit handler.How do you validate form fields reactively? Answer: Use
createMemothat 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
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