如何在React前端展示Express后端的验证错误?(PostgreSQL、Node.js)
问题:如何在前端展示Express Validator返回的验证错误
需要在前端展示后端通过return res.status(400).json({errors: errors.array()});返回的Express Validator验证错误。目前前端能在控制台打印出{errors: Array(2)},但无法通过JSX将错误信息渲染到页面。
前后端代码
前端原代码
const onSubmitForm = async (e) => { e.preventDefault(); try { const body = { aName, aLastName, aPhone, aEmail, job1, jobDesc1, job2, jobDesc2, job3, jobDesc3, edu, eduYear, certTitle }; const response = await fetch("http://localhost:5000/path", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) }); getApplicants(); } catch (err) { console.log('this line fires in catch block of client POST') console.error(err.message); } };
后端代码
app.post("/path", [ check('aName') .trim().exists({checkFalsy: true}).withMessage('Name must be at least two letters long.').bail() .isLength({ min: 2 }).withMessage('Name must be at least two letters long.').bail() .isString().withMessage('Name must be letters with apostrophe or dash'), check('aEmail') .trim().isEmail().withMessage('Must be a valid email') .normalizeEmail().toLowerCase() ], async (req, res, next) => { const { aName, aLastName, aPhone, aEmail, job1, jobDesc1, job2, jobDesc2, job3, jobDesc3, edu, eduYear, certTitle } = req.body; console.log(req.body.aName); // prints out exactly what it should const errors = validationResult(req); console.log(errors.array()); if (!errors.isEmpty()) { return res.status(400).json({errors: errors.array()}); //This holds what I want to show! } else { try { const newApplicant = await pool.query(`INSERT INTO table ( applicantName, applicantLastName, applicantPhone, applicantEmail, jobTitle1, jobDesc1, jobTitle2, jobDesc2, jobTitle3, jobDesc3, educationTitle, educationYear, certificationTitle) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) RETURNING *`, [aName, aLastName, aPhone, aEmail, job1, jobDesc1, job2, jobDesc2, job3, jobDesc3, edu, eduYear, certTitle] ); res.json(newApplicant.rows[0]); // "means accessing the first element in the array" // .rows is used to specify you JUST want rows, not a ton of other things that are in the response object. } catch (err) { console.error(err.message); } } });
服务器返回的错误数组示例
[ { "value": "J", "msg": "Name must be at least two letters long.", "param": "aName", "location": "body" }, { "value": "JohnDoe@sit", "msg": "Must be a valid email", "param": "aEmail", "location": "body" } ]
解决方案
1. 修复前端fetch的错误处理逻辑
fetch API只有在网络错误时才会触发catch块,HTTP 400这类状态码不会自动进入catch。需要在try块中手动检查response.ok,如果为false则解析错误响应并处理。
2. 将错误存入state并渲染
定义state存储错误信息,修改提交函数处理错误响应,最后在JSX中遍历错误数组渲染每个提示。
修改后的前端代码示例:
// 在组件中定义错误state const [formErrors, setFormErrors] = useState([]); const onSubmitForm = async (e) => { e.preventDefault(); // 提交前清空历史错误 setFormErrors([]); try { const body = { aName, aLastName, aPhone, aEmail, job1, jobDesc1, job2, jobDesc2, job3, jobDesc3, edu, eduYear, certTitle }; const response = await fetch("http://localhost:5000/path", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) }); // 检查响应状态 if (!response.ok) { const errorData = await response.json(); // 将后端返回的错误数组存入state setFormErrors(errorData.errors); return; } // 提交成功后的逻辑 getApplicants(); } catch (err) { console.error(err.message); } };
3. 在JSX中渲染错误
在表单合适位置添加错误渲染代码:
{formErrors.length > 0 && ( <div className="error-container"> <h4>提交失败,请检查以下问题:</h4> <ul> {formErrors.map((error, index) => ( <li key={index} className="error-item"> <strong>{error.param}:</strong> {error.msg} </li> ))} </ul> </div> )}
这样就能把Express Validator返回的错误信息正确渲染到页面上了。
内容的提问来源于stack exchange,提问作者Bret Spoehr
相关产品推荐
相关产品推荐

