React中用switch计算分数异常:提交后无显示且不跳转
问题分析与修复方案
核心错误点
- 提交按钮未在表单内:当前提交按钮位于
<form>标签外部,点击时不会触发表单的onSubmit事件,导致submitMarks函数根本没执行。 - Switch语句完全误用:
- 语法错误:正确格式是
switch(要判断的变量),而非用布尔表达式作为case条件。 - 引用错误:用
'wordday'这类固定字符串代替状态变量,无法获取用户实际选择的答案。 - 匹配错误:部分case里的字符串带多余空格(如
'yessee '),和单选框的value不匹配。 - 执行中断:每个case里的
return setMarks会直接终止函数,无法完成所有题目分数计算。
- 语法错误:正确格式是
- 第四题状态绑定错误:第四题单选框的
onChange绑定了setDayWord,应该绑定setIdentifyColor,导致第四题答案无法正确存储。 - 分数状态初始化错误:
marks初始值为字符串'',累加时会变成字符串拼接而非数字相加。 - 不必要的async修饰:
submitMarks函数没有异步操作,无需标记为async。
修复后的完整代码
import { useState } from 'react'; import { useHistory } from 'react-router-dom'; function InAnswers() { const history = useHistory(); const [dayWord, setDayWord] = useState(''); //1 const [seeObject, setSeeObject] = useState(''); //2 const [identifyObject, setIdentifyObject] = useState(''); //3 const [identifyColor, setIdentifyColor] = useState(''); //4 const [firstWord, setFirstWord] = useState(''); //5 const [marks, setMarks] = useState(0); // 初始化为数字0 function submitMarks(event) { event.preventDefault(); let totalMarks = 0; // 逐题判断加分 if (dayWord === 'wordmore5') { totalMarks += 10; } if (seeObject === 'yessee') { totalMarks += 10; } if (identifyObject === 'yesidentify') { totalMarks += 10; } if (identifyColor === 'colorsyes') { totalMarks += 10; } if (firstWord === 'firstword18') { totalMarks += 10; } setMarks(totalMarks); // 跳转页面,使用计算后的totalMarks history.push(`/questions/markspage/${totalMarks}`); } return ( <div className='container'> <div className='row'> <div className='col-4'> <div className='pb-2 px-3 d-flex flex-wrap align-items-center justify-content-between'> <h2>Questions </h2> </div> </div> <div className='col-3'></div> </div> <div className='row'> <h4 className='mb-4'> Questions </h4> <form onSubmit={submitMarks}> <div> <div className='progressCard'> <div className='p-3'> <h2>1. how many words child talk in a day?</h2> <div align='right'> <span> <div className='col-md-8 mb-4'> <div className='form-name'> <div className='form-check form-check-inline'> <input className='form-check-input' type='radio' name='wordday' id='wordless5' value='wordless5' onChange={(e) => setDayWord(e.target.value)} /> <label className='form-check-label' htmlFor='wordless5'> less 5 </label> </div> <div className='form-check form-check-inline'> <input className='form-check-input' type='radio' name='wordday' id='wordmore5' value='wordmore5' onChange={(e) => setDayWord(e.target.value)} /> <label className='form-check-label' htmlFor='wordmore5'> more than 5 </label> </div> </div> </div> </span> </div> </div> </div> <br></br> <div className='progressCard'> <div className='p-3'> <h2> 2. when you show some thing to child then is child watch there? </h2> <div align='right'> <span> <div className='col-md-8 mb-4'> <div className='form-name'> <div className='form-check form-check-inline'> <input className='form-check-input' type='radio' name='see' id='nosee' value='nosee' required onChange={(e) => setSeeObject(e.target.value)} /> <label className='form-check-label' htmlFor='nosee'> no </label> </div> <div className='form-check form-check-inline'> <input className='form-check-input' type='radio' name='see' id='yessee' value='yessee' required onChange={(e) => setSeeObject(e.target.value)} /> <label className='form-check-label' htmlFor='yessee'> yes </label> </div> </div> </div> </span> </div> </div> </div> <br></br> <div className='progressCard'> <div className='p-3'> <h2>3.When you show some thing then is child identify that </h2> <div align='right'> <span> <div className='col-md-8 mb-4'> <div className='form-name'> <div className='form-check form-check-inline'> <input className='form-check-input' type='radio' name='identify' id='noidentify' value='noidentify' required onChange={(e) => setIdentifyObject(e.target.value)} /> <label className='form-check-label' htmlFor='noidentify'> no </label> </div> <div className='form-check form-check-inline'> <input className='form-check-input' type='radio' name='identify' id='yesidentify' value='yesidentify' required onChange={(e) => setIdentifyObject(e.target.value)} /> <label className='form-check-label' htmlFor='yesidentify'> yes </label> </div> </div> </div> </span> </div> </div> </div> <br></br> <div className='progressCard'> <div className='p-3'> <h2>4. child can identify more than 5 colors</h2> <div align='right'> <span> <div className='col-md-8 mb-4'> <div className='form-name'> <div className='form-check form-check-inline'> <input className='form-check-input' type='radio' name='colors' id='colorsno' value='colorsno' required onChange={(e) => setIdentifyColor(e.target.value)} /> <label className='form-check-label' htmlFor='colorsno'> no </label> </div> <div className='form-check form-check-inline'> <input className='form-check-input' type='radio' name='colors' id='colorsyes' value='colorsyes' required onChange={(e) => setIdentifyColor(e.target.value)} /> <label className='form-check-label' htmlFor='colorsyes'> yes </label> </div> </div> </div> </span> </div> </div> </div> <br></br> <div className='progressCard'> <div className='p-3'> <h2>5.The first word child told?</h2> <div align='right'> <span> <div className='col-md-8 mb-4'> <div className='form-name'> <div className='form-check form-check-inline'> <input className='form-check-input' type='radio' name='firstword' id='firstword19' value='firstword19' required onChange={(e) => setFirstWord(e.target.value)} /> <label className='form-check-label' htmlFor='firstword19'> after 18 months </label> </div> <div className='form-check form-check-inline'> <input className='form-check-input' type='radio' name='firstword' id='firstword18' value='firstword18' required onChange={(e) => setFirstWord(e.target.value)} /> <label className='form-check-label' htmlFor='firstword18'> before 18 months </label> </div> </div> </div> </span> </div> </div> </div> {/* 将提交按钮移到form内部 */} <div className='col-xl-6 mb-4'></div> <div> <input type='submit' value='SUBMIT ANSWERS ' className='form-submit-btn' /> </div> </div> </form> </div> </div> ); } export default InAnswers;
额外说明
- 替换switch为if判断:更适合这种多独立条件的分数计算,逻辑更清晰,避免switch误用。
- 先计算总分再设置状态:因为
setMarks是异步操作,直接累加会导致状态更新不及时,所以先计算totalMarks再统一设置。 - 修正label的
for属性:React中应该用htmlFor代替for,避免和JS的for循环关键字冲突。
内容的提问来源于stack exchange,提问作者Dasun Dola
相关产品推荐
相关产品推荐

