纯React应用中如何通过React-Router Redirect传递组件Props?
嘿,我来帮你搞定这个React Router传参的问题!结合你说的纯React应用、用<Redirect>给目标组件传props的场景,我给你拆解两种实用的实现方式,直接就能套用:
方法1:通过
<Redirect>的state属性传递(推荐给复杂数据) 这个方法最适合你的场景——可以传递搜索结果这类复杂数据,而且不会把数据暴露在URL里,非常安全。
第一步:在<Search />组件里触发跳转并携带数据
首先,你得在Search组件里管理好要传递的内容(比如搜索结果searchResults、用户选的展示模式viewType),点击按钮时触发Redirect:
import { useState } from 'react'; import { Redirect } from 'react-router-dom'; function Search() { // 存储搜索结果 const [searchResults, setSearchResults] = useState([]); // 标记要跳转到哪种视图(table/calendar) const [targetView, setTargetView] = useState(null); // 控制是否要触发跳转 const [shouldRedirect, setShouldRedirect] = useState(false); // 模拟搜索逻辑,你可以换成自己的真实接口请求 const handleSearch = () => { const mockResults = [{ id: 1, title: "测试数据1" }, { id: 2, title: "测试数据2" }]; setSearchResults(mockResults); }; // 点击表格按钮,设置跳转目标和状态 const goToTableView = () => { setTargetView('table'); setShouldRedirect(true); }; // 点击日历按钮同理 const goToCalendarView = () => { setTargetView('calendar'); setShouldRedirect(true); }; // 如果需要跳转,就渲染Redirect组件 if (shouldRedirect) { // 根据目标视图选择路由路径 const path = targetView === 'table' ? '/results' : '/calendar'; return ( <Redirect to={{ pathname: path, // 这里就是要传递给目标组件的props,存到state里 state: { results: searchResults, viewMode: targetView } }} /> ); } return ( <div className="search-container"> <input type="text" placeholder="输入关键词搜索..." /> <button onClick={handleSearch}>执行搜索</button> <button onClick={goToTableView}>表格展示</button> <button onClick={goToCalendarView}>日历展示</button> </div> ); }
第二步:在目标组件(<DisplayResults />或日历组件)接收数据
目标组件可以用useLocation钩子拿到传递过来的state数据,记得做非空判断,防止用户直接访问路由时出错:
import { useLocation } from 'react-router-dom'; function DisplayResults() { const location = useLocation(); // 从state里取出数据,加个默认值避免报错 const { results, viewMode } = location.state || {}; return ( <div className="results-container"> <h2>表格模式展示</h2> <table> <thead> <tr> <th>ID</th> <th>标题</th> </tr> </thead> <tbody> {/* 遍历搜索结果渲染表格行 */} {results?.map(item => ( <tr key={item.id}> <td>{item.id}</td> <td>{item.title}</td> </tr> ))} </tbody> </table> </div> ); } // 日历组件的接收方式完全一样 function CalendarView() { const location = useLocation(); const { results, viewMode } = location.state || {}; return ( <div className="calendar-container"> <h2>日历模式展示</h2> {/* 这里用results渲染你的日历组件 */} </div> ); }
方法2:通过URL参数传递(适合简单标识)
如果只是传递“表格/日历”这种简单的模式标识,也可以把它放在URL里,这样用户还能直接分享这个页面链接。不过这种方式不适合传复杂的搜索结果,你可以把结果存在localStorage里配合使用。
第一步:配置带参数的路由
先在你的路由配置里加个带参数的路由:
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; import SearchMain from './SearchMain'; import DisplayResults from './DisplayResults'; function App() { return ( <Router> <Switch> <Route path="/search" component={SearchMain} /> {/* 用:view参数来区分展示模式 */} <Route path="/results/:view" component={DisplayResults} /> </Switch> </Router> ); }
第二步:在<Search />组件里跳转时带参数
import { useState, useHistory } from 'react'; function Search() { const history = useHistory(); const [searchResults, setSearchResults] = useState([]); const handleSearch = () => { const mockResults = [{ id: 1, title: "测试数据1" }, { id: 2, title: "测试数据2" }]; setSearchResults(mockResults); }; const goToTableView = () => { // 把搜索结果存在localStorage,因为URL存不了复杂数据 localStorage.setItem('searchResults', JSON.stringify(searchResults)); // 跳转到带table参数的路由 history.push('/results/table'); }; const goToCalendarView = () => { localStorage.setItem('searchResults', JSON.stringify(searchResults)); history.push('/results/calendar'); }; // 渲染部分和之前一样... }
第三步:在目标组件接收参数和数据
import { useParams } from 'react-router-dom'; function DisplayResults() { // 拿到URL里的view参数 const { view } = useParams(); // 从localStorage取出搜索结果 const results = JSON.parse(localStorage.getItem('searchResults')) || []; return ( <div className="results-container"> <h2>{view === 'table' ? '表格模式' : '日历模式'}展示</h2> {/* 根据view参数渲染对应的组件 */} {view === 'table' ? ( <table> {/* 表格内容 */} </table> ) : ( <div> {/* 日历内容 */} </div> )} </div> ); }
小提醒
- 用
state传递的数据在页面刷新后会消失,因为它存在内存里;如果需要刷新后还能保留数据,记得配合localStorage或者sessionStorage。 - 接收state的时候一定要加非空判断(
location.state || {}),不然用户直接输入目标路由地址会报错。 - 如果你的React Router是v6版本,
<Redirect>已经被Navigate组件替代了,用法差不多:import { Navigate } from 'react-router-dom',然后用<Navigate to={{ pathname: '/results', state: {...} }} replace />就行。
内容的提问来源于stack exchange,提问作者CiccioMiami
相关产品推荐
相关产品推荐

