React实现点击按钮提交测验分数更新数据库的方法
实现方案
你现在的代码已经在创建用户记录时预留了score字段,只需要补全「记录用户ID-后端新增更新接口-前端绑定点击事件传参」三个环节即可,具体修改如下:
1. 调整前端表单提交逻辑,持久化用户记录ID
第一次表单提交成功后,后端会返回新建用户记录的唯一_id,你需要把这个ID存下来,后续更新分数时才能定位到对应的数据库条目。同时补全更新分数的请求方法:
// formServices.js export const FormService = { store: (data) => { console.log('data===>>>', data); const { title, fname, lname, email, phoneNumber, cv, coverLetter } = data; const formData = new FormData(); formData.append('fname', fname); formData.append('lname', lname); formData.append('email', email); formData.append('phoneNumber', phoneNumber); formData.append('coverLetter', coverLetter); formData.append('title', title); formData.append('cv', cv); // 补return,向外层暴露请求Promise,才能拿到后端返回结果 return Axios.post(requests.formApi.store, formData) .then((res) => { // 提交成功后把用户ID存入本地存储,页面跳转后不会丢失 if (res.data.success) { localStorage.setItem('candidateId', res.data.data._id); } return res; }) .catch((err) => { return err; }); }, // 新增分数更新请求方法 updateScore: (candidateId, score) => { return Axios.patch(`${requests.formApi.store}/${candidateId}`, { score }); } };
2. 后端新增分数更新接口
原有store方法仅用于新建用户记录,需要新增一个更新接口处理分数写入逻辑:
首先在FormController.js中新增更新方法:
// FormController.js const form = require('../models/FormModel') module.exports = { store: (req, res, next) => { // 原有store逻辑保持不变 let candidate = new form({ title: req.body.title, fname: req.body.fname, lname: req.body.lname, email: req.body.email, phoneNumber: req.body.phoneNumber, coverLetter: req.body.coverLetter, cv: req.body.cv, score: req.body.score }) if (req.file) { candidate.cv = req.file.path } candidate.save() .then(response => { res.json({ success: true, message: 'Candidate added successfully!', data: candidate, }) }) .catch(error => { res.json({ success: false, message: 'An error occured!', error: error, }) }) }, // 新增分数更新方法 updateScore: (req, res, next) => { const candidateId = req.params.id; const { score } = req.body; form.findByIdAndUpdate(candidateId, { score }, { new: true }) .then(response => { res.json({ success: true, message: 'Score saved successfully', data: response }) }) .catch(error => { res.json({ success: false, message: 'Failed to save score', error }) }) } }
接着在你的后端路由文件中,新增PATCH路由指向上面的updateScore方法:
// 路由配置示例,路径和你现有项目保持一致即可 router.patch('/form/:id', FormController.updateScore);
3. 给Apply按钮绑定点击触发逻辑
修改Quiz页的EndScreen组件,引入FormService,给按钮绑定点击事件,点击时读取之前存储的用户ID和当前测验分数,调用更新接口完成写入:
// Quiz.js import { FormService } from '替换为你项目中formServices的实际路径'; function EndScreen() { const { score } = useContext(QuizContext); const handleApplyClick = async () => { const candidateId = localStorage.getItem('candidateId'); if (!candidateId) { alert('Invalid user status, please resubmit the form'); return; } try { const res = await FormService.updateScore(candidateId, score); if (res.data.success) { // 提交成功后的逻辑,比如跳转成功页、提示用户 alert('Application submitted!'); // 清掉本地存储的用户ID,避免重复提交 localStorage.removeItem('candidateId'); } else { alert('Submit failed, please try again'); } } catch (err) { console.error('Score update error:', err); alert('Network error, please retry later'); } } return ( <div className='EndScreen'> <h1>Test finished</h1> <br></br> <h3> You scored:</h3> <h1 style={{ fontSize: '70px' }}>{score}/{Questions.length}</h1> <br></br> <br></br> <button onClick={handleApplyClick}>Apply</button> </div> ) }
补充说明:如果不想用localStorage存用户ID,也可以把ID放到你已经在用的QuizContext全局状态里,只要保证跳转到测验页后能拿到第一次表单提交生成的用户唯一ID即可,这个ID是定位数据库对应记录的核心参数,不能丢失。
内容的提问来源于stack exchange,提问作者Darkpsinight
相关产品推荐
相关产品推荐

