# 表单验证与提交

URL: https://caijiao.org/react/chapter6/form-validation
Source: docs/react/chapter6/form-validation.md
Description: 在 React 中，表单验证可以通过状态管理和条件判断实现。在提交表单时，通常会验证用户输入的内容并进行相应的处理。

## 表单验证

在 React 中，表单验证通常是基于组件的状态，通过 `useState` 记录输入值，并在提交时进行检查。

```jsx
import { useState } from 'react';

function Form() {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [error, setError] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();

    // 基本验证：确保 name 和 email 都已填写
    if (!name || !email) {
      setError('请填写所有字段');
      return;
    }

    // 提交表单逻辑
    console.log('表单提交:', { name, email });
    setError('');
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>姓名</label>
        <input
          type="text"
          value={name}
          onChange={(e) => setName(e.target.value)}
        />
      </div>

      <div>
        <label>邮箱</label>
        <input
          type="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
        />
      </div>

      {error && <p style={{ color: 'red' }}>{error}</p>}

      <button type="submit">提交</button>
    </form>
  );
}
````

## 常见验证类型

1. **必填字段**：确保用户填写了表单中的每个字段。
2. **格式验证**：例如检查电子邮件格式或电话号码格式。
3. **密码强度**：检查密码是否符合安全要求。

```jsx
// 简单的邮箱格式验证
const isValidEmail = (email) => /\S+@\S+\.\S+/.test(email);

const handleSubmit = (e) => {
  e.preventDefault();

  if (!name || !email) {
    setError('请填写所有字段');
    return;
  }

  if (!isValidEmail(email)) {
    setError('请输入有效的邮箱地址');
    return;
  }

  console.log('表单提交:', { name, email });
  setError('');
};
```

## 表单提交

表单提交时，通常需要通过 API 或其他方式进行处理。

```jsx
import { useState } from 'react';

function SubmitForm() {
  const [formData, setFormData] = useState({ name: '', email: '' });
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  const handleSubmit = async (e) => {
    e.preventDefault();
    setLoading(true);

    // 模拟 API 请求
    try {
      const response = await fakeApiRequest(formData);
      console.log('提交成功:', response);
      setLoading(false);
    } catch (err) {
      setError('提交失败，请稍后再试');
      setLoading(false);
    }
  };

  const fakeApiRequest = (data) =>
    new Promise((resolve, reject) => setTimeout(() => resolve(data), 1000));

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>姓名</label>
        <input
          type="text"
          value={formData.name}
          onChange={(e) => setFormData({ ...formData, name: e.target.value })}
        />
      </div>

      <div>
        <label>邮箱</label>
        <input
          type="email"
          value={formData.email}
          onChange={(e) => setFormData({ ...formData, email: e.target.value })}
        />
      </div>

      {error && <p style={{ color: 'red' }}>{error}</p>}

      <button type="submit" disabled={loading}>
        {loading ? '提交中...' : '提交'}
      </button>
    </form>
  );
}
```

## 总结

在 React 中，表单验证是通过组件状态和事件处理实现的。可以进行简单的字段验证、格式检查以及异步提交处理。通过 `useState` 控制输入状态，并在表单提交时进行验证和提交处理，确保数据的有效性和安全性。
