React路由问题:仅表单提交后允许访问ExamResult嵌套路由
解决嵌套路由访问限制问题(仅允许提交表单后访问)
方案一:通过导航State验证(基础版)
先创建一个路由守卫组件RequireSubmission,用来校验是否是通过表单提交跳转过来的:
import { Navigate, useLocation } from 'react-router-dom'; export function RequireSubmission({ children }) { const location = useLocation(); // 校验是否携带了提交时传递的state数据,可根据你实际传递的字段调整判断逻辑 const isSubmitted = location.state?.examResult !== undefined; if (!isSubmitted) { // 未提交则跳回上级考试页面,也可替换为404组件 return <Navigate to=".." replace />; } return children; }
接着修改路由配置,给result路由加上这个守卫:
<Routes> ... <Route path='exams/:id' element={<ExamPage />} > <Route path='result' element={<RequireSubmission><ExamResult /></RequireSubmission>} /> </Route> <Route path='exams/:id/add-question' element={<RequireAuth><AddQuestion /></RequireAuth>}/> ... <Route path='*' element={<NoMatch />} /> </Routes>
方案二:结合本地存储(解决刷新失效问题)
如果用户刷新页面,路由的state会丢失,这时候需要用localStorage记录提交状态:
- 提交表单时同步存储状态:
// QuestionList.js中的提交逻辑 const handleSubmit = () => { // 处理表单提交,生成结果数据 const examResult = { /* 你的结果数据 */ }; // 用考试ID作为key,存储提交状态 localStorage.setItem(`exam_submitted_${examId}`, JSON.stringify(examResult)); // 携带state跳转到结果页 navigate('result', { state: { examResult } }); };
- 更新
RequireSubmission组件,同时校验state和本地存储:
import { Navigate, useLocation, useParams } from 'react-router-dom'; export function RequireSubmission({ children }) { const location = useLocation(); const { id: examId } = useParams(); const hasStateResult = location.state?.examResult !== undefined; const hasStoredResult = localStorage.getItem(`exam_submitted_${examId}`) !== null; if (!hasStateResult && !hasStoredResult) { return <Navigate to=".." replace />; } return children; }
额外优化:重置提交状态
如果需要用户每次进入考试页都能重新提交,可以在ExamPage组件中清除对应考试的存储记录:
// ExamPage组件 import { useEffect, useParams } from 'react'; function ExamPage() { const { id: examId } = useParams(); useEffect(() => { // 进入考试页时清除之前的提交记录 localStorage.removeItem(`exam_submitted_${examId}`); }, [examId]); // 组件其他逻辑... }
内容的提问来源于stack exchange,提问作者Alon Kolyakov
相关产品推荐
相关产品推荐

