React.js表单输入验证问题:首次提交空字段仍触发提交提示
The main problem here is that React state updates are asynchronous. When you call setFormError in your submit handler, the formError state doesn't update immediately. So when you check zipError === '' && aadharError === '' right after setting those errors, you're still looking at the original state values (which are empty when the component first renders)—hence the success alert fires even when fields are empty. On subsequent clicks, the state holds errors from the previous submit, so the check fails unless you've fixed the fields and cleared errors via onChange.
Here's how to fix this by validating first with local variables, then updating state and checking for success:
import React, { useState, Fragment } from 'react' import validator from 'validator' const ValForm = () => { const [formData, setFormData] = useState({ pinCode: '', aadhar: '' }) const [formError, setFormError] = useState({ zipError: '', aadharError: '' }) const { pinCode, aadhar } = formData; const { zipError, aadharError } = formError; const onChange = e => { setFormData({ ...formData, [e.target.name]: e.target.value }) setFormError({ ...formError, zipError: '', aadharError: '' }) } const onSubmit = async e => { e.preventDefault(); // Create a local object to hold validation errors const newErrors = { zipError: '', aadharError: '' }; // Validate each field and populate newErrors if (validator.isEmpty(pinCode)) { newErrors.zipError = "Please enter pin code."; } if (validator.isEmpty(aadhar)) { newErrors.aadharError = "Please enter aadhar number."; } // Update the error state with our local errors setFormError(newErrors); // Check if there are no errors (both error fields are empty) const hasNoErrors = Object.values(newErrors).every(error => error === ''); if (hasNoErrors) { alert("Form is good to submit."); // Add your actual form submission logic here (e.g., API call) } } return ( <Fragment> <h1>Please make sure it's you only:</h1> <form onSubmit={onSubmit}> <label>PinCode:</label> <br /> <input type="text" // Fixed invalid input type placeholder="Enter your pin code" name="pinCode" id="pinCode" value={pinCode} onChange={onChange} /> <br /> <div className="err_class">{zipError}</div> <label>Aadhar Number:</label> <br /> <input type="text" // Fixed invalid input type placeholder="Enter your Aadhar number" name="aadhar" id="aadhar" value={aadhar} onChange={onChange} /> <br /> <div className="err_class">{aadharError}</div> <br /> <button type="submit">Submit</button> </form> </Fragment> ) } export default ValForm
Key Changes Explained:
- Local Error Object: We use a local
newErrorsobject to collect validation results instead of updating state directly during validation. This lets us check for errors immediately without waiting for React's state update cycle. - Error Check: Instead of relying on state values, we check the local
newErrorsobject usingObject.values(newErrors).every(...)to confirm there are no errors. - Single State Update: We only update the
formErrorstate once we've collected all errors, ensuring the UI reflects the latest validation status. - Input Type Fix: Changed
type="input"totype="text"since "input" isn't a valid HTML input type.
This approach ensures your validation works correctly on the first submit, and the success alert only triggers when both fields are filled out properly.
内容的提问来源于stack exchange,提问作者Pramod

