Skip to content

Instantly share code, notes, and snippets.

@lejonmanen
Created April 1, 2026 16:22
Show Gist options
  • Select an option

  • Save lejonmanen/07f6c136dd559793dac67726b529a5c0 to your computer and use it in GitHub Desktop.

Select an option

Save lejonmanen/07f6c136dd559793dac67726b529a5c0 to your computer and use it in GitHub Desktop.
React-formulär med validering
/*
Exempel på validering av formulär
Förbättringar:
+ Flytta valideringslogik till en separat hook för återanvändbarhet.
+ Lägg till fokus på första fel för bättre tillgänglighet: inputRef.current.focus()
+ Lägg till visuell feedback på input (t.ex. border-färg) för bättre UX. Återkoppla med mer än färg.
*/
import { useState } from "react";
export default function LoginForm() {
const [values, setValues] = useState({ email: "", password: "" });
const [errors, setErrors] = useState({});
const [touched, setTouched] = useState(false);
const validate = (vals) => {
const errs = {};
if (!vals.email) errs.email = "E-post krävs";
else if (!/\S+@\S+\.\S+/.test(vals.email)) errs.email = "Ogiltig e-post";
if (!vals.password) errs.password = "Lösenord krävs";
else if (vals.password.length < 6) errs.password = "Minst 6 tecken";
return errs;
};
const handleChange = (e) => {
const { name, value } = e.target;
const newValues = { ...values, [name]: value };
setValues(newValues);
if (touched) setErrors(validate(newValues)); // validera efter första försök
};
const handleSubmit = (e) => {
e.preventDefault();
setTouched(true);
const validationErrors = validate(values);
setErrors(validationErrors);
if (Object.keys(validationErrors).length === 0) {
console.log("Submitting", values);
}
};
return (
<form onSubmit={handleSubmit} noValidate>
<div>
<label htmlFor="email">E-post</label>
<input
type="email"
id="email"
name="email"
value={values.email}
onChange={handleChange}
aria-invalid={errors.email ? "true" : "false"}
aria-describedby="email-error"
/>
{errors.email && (
<span id="email-error" role="alert" style={{ color: "red" }}>
{errors.email}
</span>
)}
</div>
<div>
<label htmlFor="password">Lösenord</label>
<input
type="password"
id="password"
name="password"
value={values.password}
onChange={handleChange}
aria-invalid={errors.password ? "true" : "false"}
aria-describedby="password-error"
/>
{errors.password && (
<span id="password-error" role="alert" style={{ color: "red" }}>
{errors.password}
</span>
)}
</div>
<button type="submit">Logga in</button>
</form>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment