第9章:表单处理
简要说明
表单是 Web 应用中必不可少的组成部分,用于用户输入数据。在 React 中,表单的处理可以通过组件来实现,这些组件能够管理输入数据并将其传递到后端进行处理。本章将帮助你理解 React 中表单的基本处理方式,包括如何监听输入事件、管理表单数据,以及如何实现表单验证。
9.1 受控组件与非受控组件
9.1.1 受控组件
受控组件是指表单元素的值由 React 组件的状态(state)管理,而不是由表单元素本身管理。受控组件在 React 中是最常见的做法,因为它确保数据的状态是可预测的。
示例:受控组件的实现
import React, { useState } from 'react';
export default function ControlledComponent() {
const [inputValue, setInputValue] = useState('');
const handleChange = (e) => {
setInputValue(e.target.value);
};
return (
<div>
<input
type="text"
value={inputValue}
onChange={handleChange}
placeholder="请输入内容..."
/>
<p>输入的值:{inputValue}</p>
</div>
);
}
9.1.2 非受控组件
非受控组件是指表单元素的值由 DOM 元素本身管理,而不是由 React 的状态管理。这种情况下,React 使用 ref
来访问表单元素的值。
示例:非受控组件的实现
import React, { useState, useRef } from 'react';
export default function UncontrolledComponent() {
const inputRef = useRef(null);
const [submittedValue, setSubmittedValue] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
setSubmittedValue(inputRef.current.value);
};
return (
<div>
<form onSubmit={handleSubmit}>
<input
type="text"
ref={inputRef}
placeholder="请输入内容..."
/>
<button type="submit">提交</button>
</form>
<p>{submittedValue}</p>
</div>
);
}
总结
- 受控组件的优点是数据集中管理,适合复杂的表单逻辑。
- 非受控组件适用于简单的场景,但需要使用
ref
来访问 DOM 元素。
9.2 表单数据的获取与提交
在 React 中,表单数据的获取与提交通常需要结合组件的状态和事件处理函数来实现。
9.2.1 获取表单数据
通过组件的状态管理,可以实时获取用户输入的表单数据。
示例:获取表单数据
import React, { useState } from 'react';
export default function FormHandling() {
const [formData, setFormData] = useState({
username: '',
email: '',
});
const handleInputChange = (e) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value,
});
};
return (
<form>
<div>
<label>
用户名:
<input
type="text"
name="username"
value={formData.username}
onChange={handleInputChange}
placeholder="请输入用户名"
/>
</label>
</div>
<div>
<label>
邮箱:
<input
type="email"
name="email"
value={formData.email}
onChange={handleInputChange}
placeholder="请输入邮箱"
/>
</label>
</div>
</form>
);
}
9.2.2 提交表单数据
提交表单数据时,可以使用 onSubmit
事件处理函数拦截表单提交,默认的表单提交行为会被阻止,从而可以通过 JavaScript 处理数据。
示例:提交表单数据
import React, { useState } from 'react';
export default function FormSubmit() {
const [formData, setFormData] = useState({
username: '',
email: '',
});
const handleSubmit = (e) => {
e.preventDefault();
// 处理表单提交逻辑
console.log('表单数据:', formData);
// 这里可以将 formData 发送到后端
};
const handleInputChange = (e) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value,
});
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>
用户名:
<input
type="text"
name="username"
value={formData.username}
onChange={handleInputChange}
placeholder="请输入用户名"
/>
</label>
</div>
<div>
<label>
邮箱:
<input
type="email"
name="email"
value={formData.email}
onChange={handleInputChange}
placeholder="请输入邮箱"
/>
</label>
</div>
<button type="submit">提交</button>
</form>
);
}
9.3 表单验证的基本实现
表单验证是确保用户输入符合预期的重要步骤。React 中可以结合状态和事件处理函数实现简单的表单验证,也可以使用第三方库(如 yup
和 react-hook-form
)来简化验证逻辑。
9.3.1 基于状态的验证
示例:简单的表单验证
import React, { useState } from 'react';
export default function FormValidation() {
const [formData, setFormData] = useState({
username: '',
email: '',
});
const [errors, setErrors] = useState({
username: '',
email: '',
});
const handleSubmit = (e) => {
e.preventDefault();
// 验证逻辑
let isValid = true;
// 验证用户名
if (formData.username.trim() === '') {
setErrors({
...errors,
username: '用户名不能为空',
});
isValid = false;
}
// 验证邮箱
if (formData.email.trim() === '') {
setErrors({
...errors,
email: '邮箱不能为空',
});
isValid = false;
}
if (isValid) {
// 提交表单
console.log('表单数据:', formData);
}
};
const handleInputChange = (e) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value,
});
// 清空错误提示
setErrors({
...errors,
[name]: '',
});
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>
用户名:
<input
type="text"
name="username"
value={formData.username}
onChange={handleInputChange}
placeholder="请输入用户名"
/>
{errors.username && <span className="error">{errors.username}</span>}
</label>
</div>
<div>
<label>
邮箱:
<input
type="email"
name="email"
value={formData.email}
onChange={handleInputChange}
placeholder="请输入邮箱"
/>
{errors.email && <span className="error">{errors.email}</span>}
</label>
</div>
<button type="submit">提交</button>
</form>
);
}
9.3.2 使用第三方库
使用第三方库可以简化表单验证的逻辑。例如,yup
是一个流行的验证库,react-hook-form
是一个专门处理表单的库。
示例:使用 yup
和 react-hook-form
import React from 'react';
import { useForm } from 'react-hook-form';
import * as yup from 'yup';
const schema = yup.object().shape({
username: yup.string().required('用户名不能为空'),
email: yup.string().email('请输入有效的邮箱格式').required('邮箱不能为空'),
});
export default function FormValidationWithLibraries() {
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: yupResolver(schema),
});
const onSubmit = (formData) => {
console.log('表单数据:', formData);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label>
用户名:
<input
{...register('username')}
placeholder="请输入用户名"
/>
{errors.username && <span className="error">{errors.username.message}</span>}
</label>
</div>
<div>
<label>
邮箱:
<input
{...register('email')}
placeholder="请输入邮箱"
/>
{errors.email && <span className="error">{errors.email.message}</span>}
</label>
</div>
<button type="submit">提交</button>
</form>
);
}
总结
本章介绍了 React 中表单处理的基本方法,包括受控组件与非受控组件、表单数据的获取与提交,以及表单验证的基本实现。通过这些内容,你能够实现基本的表单功能,并在此基础上进一步学习更复杂的表单处理技巧。
提示:在实际项目中,建议使用
react-hook-form
等第三方库来简化表单处理和验证逻辑。