React中如何将Quiz组件的result状态作为Props传递给Profile组件
解决方案:跨路由组件传递测验结果
你的问题核心是跨路由组件的状态共享,之前的尝试失败是因为result和setResult是Quiz内部的状态,App组件里根本没定义这两个变量,直接在路由里引用会报未定义错误。同时路由切换时组件会卸载重建,内部状态会丢失,所以需要把状态提升到父组件,或者用其他方式传递。下面是三种适合新手的解决方案:
方法一:状态提升到App组件(最基础的React方式)
把result状态放到顶层的App组件里,让Quiz负责更新状态,Profile负责读取状态。
步骤1:修改App.js
在App里定义状态并传递给子组件:
import { useState } from 'react'; // 其他导入不变 function App() { // 在App里定义共享的result状态 const [result, setResult] = useState(0); return ( <ApolloProvider client={client}> <Router> <NavBar /> <Routes> {/* 把setResult传给Quiz,让它能更新App里的状态 */} <Route path='/' element={<Quiz setResult={setResult} />} /> {/* 把result传给Profile,用于展示 */} <Route path='/me' element={<Profile result={result} />} /> <Route path="/profiles/:username" element={<Profile />}/> </Routes> </Router> <Footer /> </ApolloProvider> )}; export default App;
步骤2:修改Quiz.js
删除内部的result和setResult,改用props传入的setResult来更新状态:
// 去掉内部的const [result, setResult] = useState(0); const Quiz = ({ setResult }) => { const { loading, data, error } = useQuery(QUERY_QUIZ); const quizzes = data?.quizzes || []; const [currentQuestion, setCurrentQuestion] = useState(0); const [selectedAnswer, setSelectedAnswer] = useState(null); const [isQuizComplete, setIsQuizComplete] = useState(false); const [answer, setAnswer] = useState(null); const [isButtonDisabled, setIsButtonDisabled] = useState(false); // ... 其他代码不变 const handleNextQuestion = () => { // 假设这里计算新的结果值,比如答对加1 const newResult = /* 你的计算逻辑 */; // 调用App传过来的setResult更新全局状态 setResult(newResult); // ... 其他逻辑 } return ( // 你的渲染代码,展示当前结果的话可以自己临时存一个局部变量,或者从App传result过来(如果需要在Quiz里展示) ); }; export default Quiz;
步骤3:修改Profile.js
接收result props并展示:
const Profile = ({ result }) => { // ... 其他代码 return ( <div> <h2>你的测验结果:{result}</h2> {/* 其他内容 */} </div> ); }; export default Profile;
方法二:路由跳转时传递状态(适合一次性跳转传递)
如果用户是做完测验后跳转到Profile页面,可以通过react-router-dom的路由状态传递数据,不需要把状态放到App里。
步骤1:修改Quiz.js
导入useNavigate,完成测验时跳转并传递result:
import { useNavigate } from 'react-router-dom'; const Quiz = () => { const navigate = useNavigate(); // ... 其他状态和逻辑不变 const handleQuizComplete = () => { // 完成测验后,跳转到Profile并传递result navigate('/me', { state: { quizResult: result } }); } return ( // 渲染代码,比如完成按钮触发handleQuizComplete ); };
步骤2:修改Profile.js
导入useLocation读取路由状态:
import { useLocation } from 'react-router-dom'; const Profile = () => { const location = useLocation(); // 读取传递的结果,默认值设为0防止报错 const result = location.state?.quizResult || 0; return ( <div> <h2>你的测验结果:{result}</h2> </div> ); };
方法三:用localStorage持久化结果(刷新页面不丢失)
如果需要结果在页面刷新后依然保留,可以把结果存在浏览器的localStorage里。
步骤1:修改Quiz.js
完成测验时保存结果到localStorage:
const Quiz = () => { // ... 其他状态和逻辑不变 const handleQuizComplete = () => { // 保存结果到localStorage localStorage.setItem('quizResult', result.toString()); // 跳转到Profile navigate('/me'); } };
步骤2:修改Profile.js
从localStorage读取结果:
import { useState, useEffect } from 'react'; const Profile = () => { const [result, setResult] = useState(0); useEffect(() => { // 组件挂载时读取localStorage里的结果 const savedResult = localStorage.getItem('quizResult'); if (savedResult) { setResult(Number(savedResult)); } }, []); return ( <div> <h2>你的测验结果:{result}</h2> </div> ); };
内容的提问来源于stack exchange,提问作者BoSalinas
相关产品推荐
相关产品推荐

