React Router获取URL参数后隐藏地址栏参数的实现问题
问题:隐藏URL中的敏感参数并保持当前组件页面
我有一个URL:http://localhost:3000/MockApi/getDetails/A1B@$CZSK_2,希望在跳转到对应的App组件后,隐藏地址栏URL中的A1B@$CZSK_2部分,同时停留在该组件页面。尝试过MemoryRouter、useNavigate、useHistory,但都没有效果,寻求解决方案。
现有代码
App组件代码
import 'bootstrap/dist/css/bootstrap.min.css'; import './App.css'; import React, { useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; function App() { const [data, setData] = useState<any>(null); const { key } = useParams(); useEffect(() => { const apiUrl = `http://localhost:8080/MockApi/getDetails/${key}`; fetch(apiUrl) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { setData(data); console.log(data); }) .catch(error => { console.error('Error fetching data:', error); }); }, [key]); return ( <div className="container col-12 col-md-3 mt-5 "> <div> <div className="row justify-content-center border border-secondary p-3 rounded text-center shadow"> <div className="col-md-7"> <h2 className="text-center">ABC Company</h2> <form className="mt-3 text-center"> <div className='container'> {data && <h4 className="text-center pt-5">MSISDN: {data.msisdn}</h4>} {data && <h4 className="text-center pt-5">ServerRef: {data.severRef}</h4>} </div> <div className="mb-3 pt-5 text-center"> <input type="text" name="OTP" className="form-control" placeholder="OTP" /> </div> <button type="submit" className="btn btn-primary w-100"> Submit </button> </form> </div> </div> </div> </div> ); } export default App;
路由配置代码
import './App.css'; import '../node_modules/bootstrap/dist/css/bootstrap.min.css'; import {BrowserRouter as Routes, Route, Router } from 'react-router-dom'; import Home from './home'; function MainApp() { return ( <div className="App"> <Router basename='/api' location={"/"} navigator={}> <Routes> <Route path="/MockApi/getDetails/:key" element={<Home />} /> </Routes> </Router> </div> ); } export default MainApp;
解决方案
1. 修正路由配置错误
你的路由导入和使用存在错误,BrowserRouter不能别名成Routes,同时需要添加无参数的路由规则,确保URL修改后组件仍能匹配:
import './App.css'; import '../node_modules/bootstrap/dist/css/bootstrap.min.css'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import Home from './home'; // 注意:确保组件导入路径与实际文件一致 function MainApp() { return ( <div className="App"> <Router basename='/api'> <Routes> {/* 不带参数的路由,用于隐藏参数后的URL匹配 */} <Route path="/MockApi/getDetails" element={<Home />} /> {/* 带参数的路由,用于初始跳转 */} <Route path="/MockApi/getDetails/:key" element={<Home />} /> </Routes> </Router> </div> ); } export default MainApp;
2. 在App组件中修改URL并保留参数数据
使用useNavigate的replace方法替换当前URL,同时将参数存储在组件状态中,避免路由跳转后丢失数据:
import 'bootstrap/dist/css/bootstrap.min.css'; import './App.css'; import React, { useEffect, useState } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; function App() { const [data, setData] = useState<any>(null); const [apiKey, setApiKey] = useState<string | undefined>(undefined); const { key } = useParams(); const navigate = useNavigate(); useEffect(() => { // 优先使用组件内部存储的key,避免路由跳转后丢失参数 const targetKey = apiKey || key; if (!targetKey) return; const apiUrl = `http://localhost:8080/MockApi/getDetails/${targetKey}`; fetch(apiUrl) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { setData(data); // 仅在初始带参数跳转时修改URL if (key && !apiKey) { setApiKey(key); // 替换URL为不带参数的路径,不会添加历史记录 navigate('/MockApi/getDetails', { replace: true }); } }) .catch(error => { console.error('Error fetching data:', error); }); }, [key, apiKey, navigate]); return ( <div className="container col-12 col-md-3 mt-5 "> <div> <div className="row justify-content-center border border-secondary p-3 rounded text-center shadow"> <div className="col-md-7"> <h2 className="text-center">ABC Company</h2> <form className="mt-3 text-center"> <div className='container'> {data && <h4 className="text-center pt-5">MSISDN: {data.msisdn}</h4>} {data && <h4 className="text-center pt-5">ServerRef: {data.severRef}</h4>} </div> <div className="mb-3 pt-5 text-center"> <input type="text" name="OTP" className="form-control" placeholder="OTP" /> </div> <button type="submit" className="btn btn-primary w-100"> Submit </button> </form> </div> </div> </div> </div> ); } export default App;
关键说明
- 使用
navigate.replace而非navigate.push:替换当前历史记录条目,避免用户点击后退回到带参数的URL。 - 组件内部存储
apiKey:路由跳转后useParams无法获取参数,将参数存在状态中确保后续操作能正常获取。 - 添加无参数路由规则:保证URL修改后,组件仍能被正确匹配渲染。
内容的提问来源于stack exchange,提问作者Nirosh
相关产品推荐
相关产品推荐

