基于JSON的测验应用如何实现返回按钮返回上一已选步骤
测验应用返回上一步功能实现方案
核心实现依赖步骤历史栈记录用户的访问路径,不需要额外在接口数据里反向查询步骤关联,实现逻辑简单可靠:
- 新增状态存储全量步骤数据,避免每次跳转/返回都重复发接口请求
- 新增状态维护浏览历史栈,栈的顺序和用户访问步骤的顺序完全一致
- 正向跳转时将新步骤ID压入栈顶,再加载对应步骤内容
- 返回时判断栈长度,非初始页就弹出当前栈顶ID,取新的栈顶ID加载上一步内容,同时同步单选框的选中状态
修正后可直接参考的代码
import { useState, useEffect } from 'react' import axios from 'axios' // 可根据实际数据结构调整类型 type StepOption = { optionTitle: string destinationStepId: string } type Step = { id: string title: string type: 'qs' | 'instruction' options?: StepOption[] instruction?: string } const QuizApp = () => { const [allSteps, setAllSteps] = useState<Step[]>([]) // 当前展示的步骤数据 const [currentStepData, setCurrentStepData] = useState<Step | null>(null) // 步骤历史栈,初始值替换成实际第一道题的步骤ID const [stepHistory, setStepHistory] = useState<string[]>(['step-1']) const [isChecked, setIsChecked] = useState<string | null>(null) // 组件初始化时只拉一次全量步骤数据 useEffect(() => { axios.get('http://localhost:5000/steps').then((res) => { setAllSteps(res.data) // 加载初始步骤 const firstStep = res.data.find((item: Step) => item.id === stepHistory[0]) setCurrentStepData(firstStep) }) }, []) // 正向跳转到指定步骤 const navigateTo = (targetStepId: string) => { const targetStep = allSteps.find((item) => item.id === targetStepId) if (!targetStep) return // 新步骤压入历史栈 setStepHistory(prev => [...prev, targetStepId]) setCurrentStepData(targetStep) setIsChecked(targetStepId) } // 返回上一步 const navigateBack = () => { // 历史栈长度大于1才允许返回,避免在首页点返回报错 if (stepHistory.length <= 1) return // 复制历史栈,弹出当前所在的步骤ID const newHistory = [...stepHistory] newHistory.pop() // 新的栈顶就是上一步的ID const prevStepId = newHistory[newHistory.length - 1] const prevStep = allSteps.find((item) => item.id === prevStepId) if (!prevStep) return setStepHistory(newHistory) setCurrentStepData(prevStep) // 同步上一步的选中状态 setIsChecked(prevStepId) } const handleStepChange = (destinationStepId: string) => { navigateTo(destinationStepId) } if (!currentStepData) return <div>加载中...</div> return ( <div> <div>{currentStepData.title}<br /></div> {currentStepData.type === "qs" ? currentStepData.options?.map((step, index) => ( <div key={index}> <input type="radio" onChange={() => handleStepChange(step.destinationStepId)} name="stepOption" checked={isChecked === step.destinationStepId} /> {step.optionTitle} </div> )) : currentStepData.instruction } {/* 返回按钮,在首页时自动禁用 */} <button onClick={navigateBack} disabled={stepHistory.length <= 1} style={{ marginTop: '20px' }} > 返回上一步 </button> </div> ) } export default QuizApp
如果测验需要支持返回后修改选项、重新选择走不同分支,现有逻辑已经兼容——用户重新选择选项时会把新步骤压入栈,不会影响历史记录的正确性。
内容的提问来源于stack exchange,提问作者Margarita Stamova
相关产品推荐
相关产品推荐

