如何为ReactJS表单添加验证?现有注册表单验证失效求助
Hey there! Let's break down why your form validation isn't working and get it sorted out. The main issue right now is that you're bypassing the native form submission flow (and Semantic UI React's form capabilities) by using a direct onClick handler on your button. Here's how to fix it step by step:
Why Your Current Setup Isn't Working
You added the native required attribute to your inputs, but since you're calling postData directly via onClick, the browser never triggers its built-in validation checks. Plus, Semantic UI React's Form component has its own validation system we can leverage for better control and error feedback.
Step-by-Step Solution
1. Add Error State Tracking
First, let's add state to keep track of validation errors for each field:
const [errors, setErrors] = useState({});
2. Create a Validation Function
Write a function that checks each field against your rules (we'll include required checks plus an example format check for Employee ID):
const validateForm = () => { const newErrors = {}; // Validate Employee Name if (!Employee_name.trim()) { newErrors.Employee_name = "Employee name is required"; } // Validate Employee ID (required + format example) if (!Employee_id.trim()) { newErrors.Employee_id = "Employee ID is required"; } else if (!/^[A-Z0-9]{5,10}$/.test(Employee_id)) { newErrors.Employee_id = "ID must be 5-10 uppercase letters/numbers"; } // Validate Address if (!Employee_address.trim()) { newErrors.Employee_address = "Employee address is required"; } // Validate Position if (!Employee_post.trim()) { newErrors.Employee_post = "Employee position is required"; } setErrors(newErrors); // Return true if no errors return Object.keys(newErrors).length === 0; };
3. Update Form Submission Logic
Replace your postData function with a handleSubmit function that runs validation first, then submits data only if validation passes:
const handleSubmit = (e) => { e.preventDefault(); // Prevent default form reload if (validateForm()) { axios.post(`http://localhost:5000/qo`, { Employee_name, Employee_id, Employee_address, Employee_post, }) .then(() => { alert("Data Saved"); navigate("/read"); }) .catch((err) => { alert("Failed to save data"); console.error(err); }); } };
4. Update the Form JSX
Modify your form to use Semantic UI's onSubmit event, add error feedback to fields, and make inputs fully controlled (add value prop):
return ( <div> <Form className="create-form" onSubmit={handleSubmit}> <Form.Field required error={!!errors.Employee_name}> <label>Employee Name</label> <input placeholder="Employee Name" value={Employee_name} onChange={(e) => setEmployee_name(e.target.value)} /> {errors.Employee_name && <span style={{ color: "red" }}>{errors.Employee_name}</span>} </Form.Field> <Form.Field required error={!!errors.Employee_id}> <label>Employee ID</label> <input placeholder="Employee ID" value={Employee_id} onChange={(e) => setEmployee_id(e.target.value)} /> {errors.Employee_id && <span style={{ color: "red" }}>{errors.Employee_id}</span>} </Form.Field> <Form.Field required error={!!errors.Employee_address}> <label>Employee Address</label> <input placeholder="Employee Address" value={Employee_address} onChange={(e) => setEmployee_address(e.target.value)} /> {errors.Employee_address && <span style={{ color: "red" }}>{errors.Employee_address}</span>} </Form.Field> <Form.Field required error={!!errors.Employee_post}> <label>Employee Position</label> <input placeholder="Employee Position" value={Employee_post} onChange={(e) => setEmployee_post(e.target.value)} /> {errors.Employee_post && <span style={{ color: "red" }}>{errors.Employee_post}</span>} </Form.Field> <Button type="submit">Submit</Button> </Form> </div> );
Full Modified Code
Here's the complete working code with all changes:
import React, { useState } from 'react'; import { Button, Form } from 'semantic-ui-react' import axios from 'axios'; import { useNavigate } from 'react-router'; export default function Create() { let navigate = useNavigate(); const [Employee_name, setEmployee_name] = useState(''); const [Employee_id, setEmployee_id] = useState(''); const [Employee_address, setEmployee_address] = useState(''); const [Employee_post, setEmployee_post] = useState(''); const [errors, setErrors] = useState({}); const validateForm = () => { const newErrors = {}; if (!Employee_name.trim()) { newErrors.Employee_name = "Employee name is required"; } if (!Employee_id.trim()) { newErrors.Employee_id = "Employee ID is required"; } else if (!/^[A-Z0-9]{5,10}$/.test(Employee_id)) { newErrors.Employee_id = "ID must be 5-10 uppercase letters/numbers"; } if (!Employee_address.trim()) { newErrors.Employee_address = "Employee address is required"; } if (!Employee_post.trim()) { newErrors.Employee_post = "Employee position is required"; } setErrors(newErrors); return Object.keys(newErrors).length === 0; }; const handleSubmit = (e) => { e.preventDefault(); if (validateForm()) { axios.post(`http://localhost:5000/qo`, { Employee_name, Employee_id, Employee_address, Employee_post, }) .then(() => { alert("Data Saved"); navigate("/read"); }) .catch((err) => { alert("Failed to save data"); console.error(err); }); } }; return ( <div> <Form className="create-form" onSubmit={handleSubmit}> <Form.Field required error={!!errors.Employee_name}> <label>Employee Name</label> <input placeholder="Employee Name" value={Employee_name} onChange={(e) => setEmployee_name(e.target.value)} /> {errors.Employee_name && <span style={{ color: "red" }}>{errors.Employee_name}</span>} </Form.Field> <Form.Field required error={!!errors.Employee_id}> <label>Employee ID</label> <input placeholder="Employee ID" value={Employee_id} onChange={(e) => setEmployee_id(e.target.value)} /> {errors.Employee_id && <span style={{ color: "red" }}>{errors.Employee_id}</span>} </Form.Field> <Form.Field required error={!!errors.Employee_address}> <label>Employee Address</label> <input placeholder="Employee Address" value={Employee_address} onChange={(e) => setEmployee_address(e.target.value)} /> {errors.Employee_address && <span style={{ color: "red" }}>{errors.Employee_address}</span>} </Form.Field> <Form.Field required error={!!errors.Employee_post}> <label>Employee Position</label> <input placeholder="Employee Position" value={Employee_post} onChange={(e) => setEmployee_post(e.target.value)} /> {errors.Employee_post && <span style={{ color: "red" }}>{errors.Employee_post}</span>} </Form.Field> <Button type="submit">Submit</Button> </Form> </div> ) }
Key Changes Explained
- We're using the Form's
onSubmitevent instead of a buttononClick, which triggers our validation logic before submission. - Added controlled inputs (with
valueprop) to ensure state always matches input content. - Created a custom validation function that checks required fields and adds optional format rules (like Employee ID).
- Added error messages that appear below invalid fields, using Semantic UI's
errorprop to highlight fields.
内容的提问来源于stack exchange,提问作者Aman Pradhan

