react如何设计表单
表单设计基础结构
在React中设计表单通常使用受控组件(Controlled Components)或非受控组件(Uncontrolled Components)。受控组件通过React状态管理表单数据,非受控组件依赖DOM自身处理数据。
import { useState } from 'react';
function ControlledForm() {
const [formData, setFormData] = useState({ username: '', password: '' });
const handleChange = (e) => {
const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value }));
};
const handleSubmit = (e) => {
e.preventDefault();
console.log(formData);
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
name="username"
value={formData.username}
onChange={handleChange}
/>
<input
type="password"
name="password"
value={formData.password}
onChange={handleChange}
/>
<button type="submit">Submit</button>
</form>
);
}
表单验证
通过状态管理验证逻辑,结合错误提示实现客户端验证。可自定义规则或使用库如yup或validator。

const [errors, setErrors] = useState({});
const validate = () => {
const newErrors = {};
if (!formData.username) newErrors.username = 'Username is required';
if (formData.password.length < 6) newErrors.password = 'Password too short';
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleSubmit = (e) => {
e.preventDefault();
if (validate()) {
console.log('Form is valid:', formData);
}
};
动态表单字段
通过状态管理动态增减的表单字段,适用于需要灵活调整输入项的场景。

const [fields, setFields] = useState([{ id: 1, value: '' }]);
const addField = () => {
setFields([...fields, { id: Date.now(), value: '' }]);
};
const removeField = (id) => {
setFields(fields.filter(field => field.id !== id));
};
return (
<form>
{fields.map(field => (
<div key={field.id}>
<input
value={field.value}
onChange={(e) => {/* 更新逻辑 */}}
/>
<button onClick={() => removeField(field.id)}>Remove</button>
</div>
))}
<button type="button" onClick={addField}>Add Field</button>
</form>
);
第三方库集成
使用Formik和Yup简化表单管理与验证,适合复杂表单场景。
import { Formik, Field, Form } from 'formik';
import * as Yup from 'yup';
const schema = Yup.object().shape({
username: Yup.string().required('Required'),
password: Yup.string().min(6, 'Too short').required('Required'),
});
<Formik
initialValues={{ username: '', password: '' }}
validationSchema={schema}
onSubmit={(values) => console.log(values)}
>
{({ errors }) => (
<Form>
<Field name="username" />
{errors.username && <div>{errors.username}</div>}
<Field name="password" type="password" />
{errors.password && <div>{errors.password}</div>}
<button type="submit">Submit</button>
</Form>
)}
</Formik>
性能优化
对于大型表单,使用React.memo或useCallback避免不必要的渲染。
const MemoizedInput = React.memo(({ value, onChange, name }) => (
<input
type="text"
name={name}
value={value}
onChange={onChange}
/>
));
function OptimizedForm() {
const [formData, setFormData] = useState({ field1: '', field2: '' });
const handleChange = useCallback((e) => {
const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value }));
}, []);
}






