如何使用React Router在表单场景下传递数据并实现页面跳转
健身APP表单数据传递与专属页面匹配问题
我正在开发一款健身APP,其中设有供用户填写的调研表单。期望在用户提交表单后,借助React Router将表单数据传递至personalExercise.js文件,通过条件渲染为用户匹配对应的专属运动页面。
尝试的操作流程:
- 用户在
question.js文件的调研表单中作答,提交后答案会打印至控制台; - 提交后将数据传递至
personalExercise.js,通过条件语句跳转至对应运动页面。
示例逻辑:用户选择Male、18-28、Stay Active,数据传递后通过if (gender === male && userAge === young && goals === loose weight) { return (page specified to user) }这类条件渲染跳转页面。
目前已完成部分代码,但尚未实现数据传递与跳转逻辑,相关代码如下:
现有代码
App.js
import React from 'react'; import Introduction from './components/introduction'; import Questions from './components/beginning'; import Male from './components/questions'; import {BrowserRouter as Router, Route, Routes} from 'react-router-dom'; export default function App() { return ( <Router> <Routes> <Route path= "/" element={<Introduction />} /> <Route path="/beginning" element= {<Questions />} /> <Route path="/questions" element= {<Male />} /> </Routes> </Router> ); }
PersonalExercise.js
import React from 'react'; import {NavLink} from 'react-router-dom' import 'bootstrap/dist/css/bootstrap.min.css' //purpose: To have the user see their specific exercises. function personalExercise(formData) { } // function workout(){ // }
Questions.js
import React, {useState} from 'react'; import 'bootstrap/dist/css/bootstrap.min.css' import Form from 'react-bootstrap/Form'; export default function Questions() { const[formData, setFormData] = useState({ gender: "", userAge: "", goals:"", }); function handleChange(event) { const { name, value, type, checked } = event.target; setFormData(prevFormData => { return { ...prevFormData, [name]: type === 'checkbox' ? checked : value }; }); } function handleSubmit(event) { event.preventDefault() console.log(formData) }; return ( <> <header>Questions</header> <Form onSubmit={handleSubmit}> <fieldset> <legend>What was your gender at birth</legend> <input type='radio' id = 'male' name = 'gender' value = 'male' checked={formData.gender === "male"} onChange={handleChange} /> <label htmlFor="male"> Male </label> <br /> <input type='radio' id='female' name='gender' value = 'female' checked={formData.gender === "female"} onChange={handleChange} /> <label htmlFor="female"> Female </label> <br /> </fieldset> <fieldset> <legend>How old are you?</legend> <input type='radio' id="young" name="userAge" value="young" checked={formData.userAge === "young"} onChange={handleChange} /> <label htmlFor="young"> 18-28 </label> <br /> <input type='radio' id="middleAged" name="userAge" value="middleAged" checked={formData.userAge === "middleAged"} onChange={handleChange} /> <label htmlFor="middleAged"> 29-39 </label> <br /> <input type='radio' id="older" name="userAge" value="older" checked={formData.userAge === "older"} onChange={handleChange} /> <label htmlFor="older"> 40-50 </label> <br /> <input type='radio' id="senior" name="userAge" value="senior" checked={formData.userAge === "senior"} onChange={handleChange} /> <label htmlFor="senior"> 51+ </label> <br /> </fieldset> <br /> <fieldset> <legend>What kind of fitness would you prefer?</legend> <input type="radio" id="active" name="goals" value="active" checked = {formData.goals === "active"} onChange={handleChange} /> <label htmlFor='active'>To stay active!</label> <br /> <input type="radio" id="weight" name="goals" value= "weight" checked = {formData.goals === "weight"} onChange={handleChange} /> <label htmlFor="weight"> To loose weight</label> </fieldset> <br /> <button type='submit'>Submit</button> </Form> </> ) }
解决方案
1. 调整路由配置
首先在App.js中添加PersonalExercise的路由,并修正组件导入路径(确保文件名与实际文件一致):
import React from 'react'; import Introduction from './components/introduction'; import Questions from './components/Questions'; import PersonalExercise from './components/PersonalExercise'; import {BrowserRouter as Router, Route, Routes} from 'react-router-dom'; export default function App() { return ( <Router> <Routes> <Route path="/" element={<Introduction />} /> <Route path="/beginning" element={<Questions />} /> <Route path="/personal-exercise" element={<PersonalExercise />} /> </Routes> </Router> ); }
2. 表单提交时传递数据并跳转
在Questions.js中使用useNavigate钩子实现跳转,通过路由state传递表单数据:
import React, {useState} from 'react'; import { useNavigate } from 'react-router-dom'; import 'bootstrap/dist/css/bootstrap.min.css' import Form from 'react-bootstrap/Form'; export default function Questions() { const navigate = useNavigate(); const[formData, setFormData] = useState({ gender: "", userAge: "", goals:"", }); function handleChange(event) { const { name, value, type, checked } = event.target; setFormData(prevFormData => { return { ...prevFormData, [name]: type === 'checkbox' ? checked : value }; }); } function handleSubmit(event) { event.preventDefault(); console.log(formData); // 跳转并携带表单数据 navigate('/personal-exercise', { state: formData }); }; // 原return部分代码保持不变 }
3. 接收数据并实现条件渲染
在PersonalExercise.js中使用useLocation获取传递的表单数据,编写条件渲染逻辑:
import React from 'react'; import { useLocation } from 'react-router-dom'; import 'bootstrap/dist/css/bootstrap.min.css'; function PersonalExercise() { const location = useLocation(); const formData = location.state || {}; const renderWorkoutPage = () => { const { gender, userAge, goals } = formData; // 年轻男性保持活跃的专属页面 if (gender === 'male' && userAge === 'young' && goals === 'active') { return ( <div className="container mt-5"> <h2>专属运动计划 - 年轻男性活力保持</h2> <ul className="list-group mt-3"> <li className="list-group-item">每日30分钟有氧跑</li> <li className="list-group-item">每周3次力量训练(胸、肩、臂)</li> <li className="list-group-item">每日15分钟拉伸放松</li> </ul> </div> ); } // 中年女性减重的专属页面 if (gender === 'female' && userAge === 'middleAged' && goals === 'weight') { return ( <div className="container mt-5"> <h2>专属运动计划 - 中年女性减重</h2> <ul className="list-group mt-3"> <li className="list-group-item">每日40分钟椭圆机训练</li> <li className="list-group-item">每周4次HIIT训练</li> <li className="list-group-item">搭配低卡饮食建议</li> </ul> </div> ); } // 默认页面(无匹配数据时) return ( <div className="container mt-5"> <h2>请先完成调研表单获取专属运动计划</h2> </div> ); }; return <div>{renderWorkoutPage()}</div>; } export default PersonalExercise;
补充说明
- 可根据需求扩展更多条件分支,覆盖所有用户选择组合;
- 若需要持久化数据(刷新页面不丢失),可在
handleSubmit中把formData存入localStorage,在PersonalExercise中读取; - 确保所有组件文件名和导入路径严格对应,避免路径错误。
内容的提问来源于stack exchange,提问作者user12761285
相关产品推荐
相关产品推荐

