You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现点击按钮将Quiz得分提交至数据库的前端功能

测验应用前端得分提交实现方案

问题背景

开发了一款支持用户自测、自动计算得分的测验应用,需要实现点击「提交得分」按钮后将得分写入数据库的逻辑。
目前已完成数据模型、控制器中score字段的相关配置,且通过Postman验证后端接口运行正常,得分可成功写入数据库,仅剩余前端提交逻辑待开发。

现有代码

后端代码

FormController.js

const form = require('../models/FormModel')

module.exports = {
    store: (req, res, next) => {
        let candidate = new form({
            fname: req.body.fname,
            lname: req.body.lname,
            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,
                })
            })
    }
}

FormModel.js

const mongoose = require('mongoose')
const Schema = mongoose.Schema

const formSchema = new Schema({
    fname: {
        type: String
    },
    lname: {
        type: String
    },
    score: {
        type: Number
    }
}, { timestamps: true })

const form = mongoose.model('form', formSchema)
module.exports = form

前端现有代码

Quiz.js

const finishQuiz = () => {
        if (Questions[currQuestion].answer === optionChosen) {
            setscore(score + 1);
        }
        setGameState("endScreen")
        // 待补充提交逻辑
    }

现有finishQuiz函数会在答题结束时计算最终得分,并切换到结束屏,不确定是否需要在此处添加点击事件完成提交。

核心坑点

React的setState是异步批处理的,在调用setscore(score + 1)之后立刻读取score变量,拿到的还是更新前的旧值,直接用这个值发请求会导致提交的得分错误。

两种实现方案

方案1:答题完成自动提交

不需要额外绑定点击事件,算完最终得分直接发请求即可,修正后的代码如下:

const finishQuiz = () => {
  // 提前计算最终得分存入常量,避开state异步问题
  const finalScore = Questions[currQuestion].answer === optionChosen ? score + 1 : score;
  // 更新页面展示用的得分state
  setscore(finalScore);
  setGameState("endScreen");

  // 发送POST请求提交数据,将地址替换为你Postman测试时用的接口地址即可
  fetch("/api/candidate", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      fname: 你存储用户名的state变量,
      lname: 你存储用户姓氏的state变量,
      score: finalScore // 必须用提前算好的finalScore,不能直接用score变量
    })
  })
  .then(res => res.json())
  .then(res => {
    if(res.success) {
      console.log("得分提交成功")
    } else {
      console.error("提交失败:", res.message)
    }
  })
  .catch(err => {
    console.error("请求异常:", err)
  })
}

如果项目用axios发起请求,替换fetch部分即可:

import axios from 'axios';

// 计算finalScore、更新state逻辑不变
axios.post("/api/candidate", {
  fname: 用户名变量,
  lname: 用户姓氏变量,
  score: finalScore
}).then(res => {
  console.log("提交成功", res.data)
}).catch(err => {
  console.error("提交失败", err)
})

方案2:结束屏用户点击按钮后提交

如果需要用户确认得分后再手动提交,不需要在finishQuiz里写请求逻辑,步骤如下:

  1. 先修正finishQuiz的得分计算逻辑,保证state中存储的得分正确:
const finishQuiz = () => {
  const finalScore = Questions[currQuestion].answer === optionChosen ? score + 1 : score;
  setscore(finalScore);
  setGameState("endScreen");
}
  1. 在结束屏的JSX中添加提交按钮,绑定提交事件:
{gameState === "endScreen" && (
  <div className="end-screen">
    <h2>测验完成,你的最终得分:{score}</h2>
    <button onClick={submitScore}>提交得分</button>
  </div>
)}
  1. 实现submitScore提交函数,此时state中的score已经是更新后的最终值,可以直接使用:
const submitScore = () => {
  fetch("/api/candidate", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      fname: 用户名变量,
      lname: 用户姓氏变量,
      score: score
    })
  })
  .then(res => res.json())
  .then(res => {
    if(res.success) {
      alert("得分提交成功!")
    } else {
      alert("提交失败,请重试")
    }
  })
  .catch(err => {
    alert("网络异常,请重试")
  })
}

注意事项

  • 接口地址和你Postman测试时用的地址保持一致即可
  • 如果接口需要登录鉴权,在请求headers中添加对应的token字段
  • fname、lname字段替换为你实际存储用户姓名的变量即可,如果没有收集姓名可以传空字符串,或者直接在后端模型里调整这两个字段的必填规则

内容的提问来源于stack exchange,提问作者Darkpsinight

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 17:01:28