import { useState } from 'react';
function LoginForm() {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
console.log({ username, password });
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
placeholder="用户名"
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="密码"
/>
<button type="submit">登录</button>
</form>
);
}
function UserForm() {
const [form, setForm] = useState({
name: '',
email: '',
age: '',
gender: 'male'
});
const handleChange = (e) => {
const { name, value } = e.target;
setForm(prev => ({
...prev,
[name]: value
}));
};
const handleSubmit = (e) => {
e.preventDefault();
console.log(form);
};
return (
<form onSubmit={handleSubmit}>
<input
name="name"
value={form.name}
onChange={handleChange}
placeholder="姓名"
/>
<input
name="email"
type="email"
value={form.email}
onChange={handleChange}
placeholder="邮箱"
/>
<input
name="age"
type="number"
value={form.age}
onChange={handleChange}
placeholder="年龄"
/>
<select name="gender" value={form.gender} onChange={handleChange}>
<option value="male">男</option>
<option value="female">女</option>
</select>
<button type="submit">提交</button>
</form>
);
}
function RegisterForm() {
const [form, setForm] = useState({
username: '',
email: '',
password: '',
confirmPassword: ''
});
const [errors, setErrors] = useState({});
const validate = () => {
const newErrors = {};
if (!form.username) {
newErrors.username = '用户名不能为空';
} else if (form.username.length < 3) {
newErrors.username = '用户名至少3个字符';
}
if (!form.email) {
newErrors.email = '邮箱不能为空';
} else if (!/\S+@\S+\.\S+/.test(form.email)) {
newErrors.email = '邮箱格式不正确';
}
if (!form.password) {
newErrors.password = '密码不能为空';
} else if (form.password.length < 6) {
newErrors.password = '密码至少6个字符';
}
if (form.password !== form.confirmPassword) {
newErrors.confirmPassword = '两次密码不一致';
}
return newErrors;
};
const handleSubmit = (e) => {
e.preventDefault();
const newErrors = validate();
if (Object.keys(newErrors).length === 0) {
console.log('提交成功', form);
} else {
setErrors(newErrors);
}
};
const handleChange = (e) => {
const { name, value } = e.target;
setForm(prev => ({ ...prev, [name]: value }));
if (errors[name]) {
setErrors(prev => ({ ...prev, [name]: '' }));
}
};
return (
<form onSubmit={handleSubmit}>
<div>
<input
name="username"
value={form.username}
onChange={handleChange}
placeholder="用户名"
/>
{errors.username && <span className="error">{errors.username}</span>}
</div>
<div>
<input
name="email"
type="email"
value={form.email}
onChange={handleChange}
placeholder="邮箱"
/>
{errors.email && <span className="error">{errors.email}</span>}
</div>
<div>
<input
name="password"
type="password"
value={form.password}
onChange={handleChange}
placeholder="密码"
/>
{errors.password && <span className="error">{errors.password}</span>}
</div>
<div>
<input
name="confirmPassword"
type="password"
value={form.confirmPassword}
onChange={handleChange}
placeholder="确认密码"
/>
{errors.confirmPassword && <span className="error">{errors.confirmPassword}</span>}
</div>
<button type="submit">注册</button>
</form>
);
}
import { useForm } from 'react-hook-form';
function LoginForm() {
const { register, handleSubmit, formState: { errors } } = useForm();
const onSubmit = (data) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input
{...register('username', {
required: '用户名不能为空',
minLength: { value: 3, message: '至少3个字符' }
})}
placeholder="用户名"
/>
{errors.username && <span>{errors.username.message}</span>}
<input
type="password"
{...register('password', {
required: '密码不能为空',
minLength: { value: 6, message: '至少6个字符' }
})}
placeholder="密码"
/>
{errors.password && <span>{errors.password.message}</span>}
<button type="submit">登录</button>
</form>
);
}
function RegisterForm() {
const { register, handleSubmit, watch, formState: { errors } } = useForm();
const password = watch('password');
const onSubmit = (data) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input
{...register('email', {
required: '邮箱不能为空',
pattern: {
value: /\S+@\S+\.\S+/,
message: '邮箱格式不正确'
}
})}
placeholder="邮箱"
/>
{errors.email && <span>{errors.email.message}</span>}
<input
type="password"
{...register('password', {
required: '密码不能为空',
minLength: { value: 6, message: '至少6个字符' },
pattern: {
value: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/,
message: '必须包含大小写字母和数字'
}
})}
placeholder="密码"
/>
{errors.password && <span>{errors.password.message}</span>}
<input
type="password"
{...register('confirmPassword', {
required: '请确认密码',
validate: value => value === password || '两次密码不一致'
})}
placeholder="确认密码"
/>
{errors.confirmPassword && <span>{errors.confirmPassword.message}</span>}
<button type="submit">注册</button>
</form>
);
}
function EditForm() {
const { register, handleSubmit } = useForm({
defaultValues: {
username: 'John',
email: 'john@example.com',
age: 25
}
});
return (
<form onSubmit={handleSubmit(console.log)}>
<input {...register('username')} />
<input {...register('email')} />
<input type="number" {...register('age')} />
<button type="submit">更新</button>
</form>
);
}
import { Formik, Form, Field, ErrorMessage } from 'formik';
function LoginForm() {
const initialValues = {
username: '',
password: ''
};
const validate = (values) => {
const errors = {};
if (!values.username) {
errors.username = '用户名不能为空';
}
if (!values.password) {
errors.password = '密码不能为空';
} else if (values.password.length < 6) {
errors.password = '密码至少6个字符';
}
return errors;
};
const onSubmit = (values, { setSubmitting }) => {
console.log(values);
setSubmitting(false);
};
return (
<Formik
initialValues={initialValues}
validate={validate}
onSubmit={onSubmit}
>
{({ isSubmitting }) => (
<Form>
<Field name="username" placeholder="用户名" />
<ErrorMessage name="username" component="div" />
<Field type="password" name="password" placeholder="密码" />
<ErrorMessage name="password" component="div" />
<button type="submit" disabled={isSubmitting}>
登录
</button>
</Form>
)}
</Formik>
);
}
import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';
const validationSchema = Yup.object({
username: Yup.string()
.min(3, '至少3个字符')
.required('用户名不能为空'),
email: Yup.string()
.email('邮箱格式不正确')
.required('邮箱不能为空'),
password: Yup.string()
.min(6, '至少6个字符')
.required('密码不能为空'),
confirmPassword: Yup.string()
.oneOf([Yup.ref('password')], '两次密码不一致')
.required('请确认密码')
});
function RegisterForm() {
return (
<Formik
initialValues={{
username: '',
email: '',
password: '',
confirmPassword: ''
}}
validationSchema={validationSchema}
onSubmit={(values) => console.log(values)}
>
<Form>
<Field name="username" placeholder="用户名" />
<ErrorMessage name="username" component="div" />
<Field name="email" placeholder="邮箱" />
<ErrorMessage name="email" component="div" />
<Field type="password" name="password" placeholder="密码" />
<ErrorMessage name="password" component="div" />
<Field type="password" name="confirmPassword" placeholder="确认密码" />
<ErrorMessage name="confirmPassword" component="div" />
<button type="submit">注册</button>
</Form>
</Formik>
);
}
function FileUpload() {
const [file, setFile] = useState(null);
const [preview, setPreview] = useState('');
const handleChange = (e) => {
const selectedFile = e.target.files[0];
setFile(selectedFile);
if (selectedFile && selectedFile.type.startsWith('image/')) {
const reader = new FileReader();
reader.onloadend = () => {
setPreview(reader.result);
};
reader.readAsDataURL(selectedFile);
}
};
const handleSubmit = async (e) => {
e.preventDefault();
const formData = new FormData();
formData.append('file', file);
try {
const response = await fetch('/api/upload', {
method: 'POST',
body: formData
});
const data = await response.json();
console.log('上传成功', data);
} catch (error) {
console.error('上传失败', error);
}
};
return (
<form onSubmit={handleSubmit}>
<input type="file" onChange={handleChange} accept="image/*" />
{preview && <img src={preview} alt="预览" style={{ width: 200 }} />}
<button type="submit" disabled={!file}>上传</button>
</form>
);
}
- 优先使用受控组件
- 使用表单库简化开发
- 实时验证提升用户体验
- 合理使用防抖优化性能
- 统一错误提示样式
- 表单提交时禁用按钮