如何让React中的条件JSX在再次点击提交前保持不变?
问题描述
输入错误答案并提交后,再次修改输入框内容时,还没点击提交就自动显示了正确提示。相关代码如下:
const AdditionMain = () => { const [sum, setSum] = useState(""); const [isSubmit, setIsSubmit] = useState(false); const [disabled, setDisabled] = useState(false); const randomNum1 = () => { let number1 = Math.floor(Math.random() * 50); return number1; }; const randomNum2 = () => { let number2 = Math.floor(Math.random() * 50); return number2; }; const number1 = useMemo(() => randomNum1(), []); const number2 = useMemo(() => randomNum2(), []); const result = number1 + number2; const correctAnswer = <Typography>Correct!</Typography>; const wrongAnswer = <Typography>Wrong!</Typography>; const enterAnswer = <Typography>Enter your answer!</Typography>; const onSubmit = (e) => { e.preventDefault(); setIsSubmit((prevState) => !prevState); if (sum === result) { setDisabled(!disabled); } }; return ( <> <Navbar /> <Card sx={{ marginTop: 2, height: 50, display: "flex", flexDirection: "column", alignItems: "center", }} > <Typography></Typography> </Card> <Container component="main" maxWidth="xs"> <Box sx={{ marginTop: 8, display: "flex", flexDirection: "column", alignItems: "center", }} > <Typography>Fill in the box to make the equation true.</Typography> <Typography fontSize={28}> {number1} + {number2} = </Typography> <TextField inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }} onChange={(e) => setSum(parseInt(e.target.value))} disabled={disabled} type="number" value={sum} name="sum" id="outlined-basic" label="" variant="outlined" ></TextField> {!isSubmit || (isSubmit && sum === "") ? ( <Button onClick={onSubmit} sx={{ marginTop: 1 }} variant="outlined"> Submit </Button> ) : isSubmit && sum !== result ? ( <Button onClick={onSubmit} sx={{ marginTop: 1 }} variant="outlined"> {" "} Try again! </Button> ) : ( () => {} )} {isSubmit && sum === "" ? enterAnswer : isSubmit && sum !== result ? wrongAnswer : isSubmit && sum === result ? correctAnswer : ""} {isSubmit && sum === result ? <Button>Try new one</Button> : () => {}} </Box> </Container> </> ); }; export default AdditionMain;
修复方案
问题根源
当前代码中,点击提交后isSubmit会保持true状态,而提示的判断逻辑直接绑定实时输入的sum值。只要isSubmit为true,且实时输入的sum等于正确答案,就会立刻显示"Correct!",完全没有区分用户是主动提交答案还是实时修改输入。
具体修复步骤
- 新增
submittedAnswer状态,专门存储用户每次提交的答案,只有点击提交按钮时才更新这个值; - 调整
onSubmit函数逻辑:点击提交时先记录当前输入的答案,再处理提交状态和输入框禁用逻辑; - 修改提示的判断条件,基于
submittedAnswer和result的对比,而非实时输入的sum。
修改后的完整代码
const AdditionMain = () => { const [sum, setSum] = useState(""); // 新增状态:存储用户提交的答案 const [submittedAnswer, setSubmittedAnswer] = useState(null); const [isSubmit, setIsSubmit] = useState(false); const [disabled, setDisabled] = useState(false); const randomNum1 = () => Math.floor(Math.random() * 50); const randomNum2 = () => Math.floor(Math.random() * 50); const number1 = useMemo(() => randomNum1(), []); const number2 = useMemo(() => randomNum2(), []); const result = number1 + number2; const correctAnswer = <Typography>Correct!</Typography>; const wrongAnswer = <Typography>Wrong!</Typography>; const enterAnswer = <Typography>Enter your answer!</Typography>; const onSubmit = (e) => { e.preventDefault(); // 点击提交时记录当前输入的答案 setSubmittedAnswer(sum); setIsSubmit(true); if (sum === result) { setDisabled(true); } }; // 点击Try again时重置提交状态和已提交答案 const handleTryAgain = () => { setIsSubmit(false); setSubmittedAnswer(null); }; // 生成新题目 const handleNewQuestion = () => { window.location.reload(); // 简单刷新方式,也可通过重置状态实现更优雅的刷新 }; return ( <> <Navbar /> <Card sx={{ marginTop: 2, height: 50, display: "flex", flexDirection: "column", alignItems: "center", }} > <Typography></Typography> </Card> <Container component="main" maxWidth="xs"> <Box sx={{ marginTop: 8, display: "flex", flexDirection: "column", alignItems: "center", }} > <Typography>Fill in the box to make the equation true.</Typography> <Typography fontSize={28}> {number1} + {number2} = </Typography> <TextField inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }} onChange={(e) => setSum(parseInt(e.target.value))} disabled={disabled} type="number" value={sum} name="sum" id="outlined-basic" label="" variant="outlined" ></TextField> {!isSubmit ? ( <Button onClick={onSubmit} sx={{ marginTop: 1 }} variant="outlined"> Submit </Button> ) : submittedAnswer !== result ? ( <Button onClick={handleTryAgain} sx={{ marginTop: 1 }} variant="outlined"> Try again! </Button> ) : null} {isSubmit && submittedAnswer === "" ? enterAnswer : isSubmit && submittedAnswer !== result ? wrongAnswer : isSubmit && submittedAnswer === result ? correctAnswer : ""} {isSubmit && submittedAnswer === result ? ( <Button onClick={handleNewQuestion}>Try new one</Button> ) : null} </Box> </Container> </> ); }; export default AdditionMain;
修复说明
submittedAnswer仅在用户点击提交时更新,确保提示只基于用户主动提交的答案,实时输入不会触发提示变化;- 拆分
Try again逻辑,点击后重置提交状态和已提交答案,让用户可以重新输入并提交; - 调整按钮和提示的判断逻辑,现在只有用户提交后才会根据提交的答案显示对应反馈。
内容的提问来源于stack exchange,提问作者Süleyman Eminbəyli
相关产品推荐
相关产品推荐

